Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Как установить размер стека в g++?


Автор: xni 2.1.2007, 23:09
Вот есть такая программка. Если устанавливать maxN небольшое, то все работает. Если 190 (так нужно по условию задачи) - компилирую (просто $g++ m.cpp), и получаю Segmentation Fault. Как я понимаю - программа из-за этого большого массива выходит за отведенное ей адресное пространство. Сейчас перешел на g++, и нигде не могу найти - как там изменить размер стека. Подсткажите, пожалуйста!

Код

#include <iostream>
#pragma comment(linker, "/STACK:16777216")

const int maxN=190;
const int delays[] = {0, 1, 3, 7, 15, 31, 63, 127};

int main()
{
        using namespace std;
        int A[maxN][maxN][maxN];
}


Заранее, огромное спасибо!

Автор: xni 2.1.2007, 23:31
Единственное, что нашел - изменение размера стека для всех запускаемых программ.

ulimit -s unlimited # убрать ограничения на стек
ulimit -a # показать текущие ограничения

Так я установил, что выделенных 8Мб недостаточно. Поставил 16. Запускается, работает, но мне кажется, что это не выход.

Автор: bilbobagginz 3.1.2007, 00:55
не понимаю, какую связь ты видишь между проблемой доступа в не твой регион памяти (или скажем вне границ конечного массива), и размером стека ?!?!?!

это совершенно разные вещи.




Автор: MAKCim 3.1.2007, 11:30
xni
в твоем случае никакого segmentation fault быть не может, поскольку ты нигде к массиву не обращаешься а само изменение %esp ни к чему плохому не приводит  smile  
Цитата

не понимаю, какую связь ты видишь между проблемой доступа в не твой регион памяти (или скажем вне границ конечного массива), и размером стека ?!?!?!
это совершенно разные вещи.

почему?
выделение памяти под массив в стеке происходит
Код

...
movl    %esp, %ebp
subl    $0x1A2A3E0, %esp
...

стек - область памяти с read/write доступом, под него изначально отводится некоторое пространство адресов от X до Y (X > Y)
при уменьшении %esp, значение %esp - виртуальный адрес, который может отображатся на:
 - валидную read/write область (скажем данных или стека если диапозон X - Y >= 0x1A2A3E0 (Вот оно!!))
 - код (read only)
 - если текущее значение %esp < 0x1A2A3E0, произойдет переполнение и в %esp будет содержаться отрицательное число в дополнительном коде, НО процессор об этом ничего не знает, а т. к это число скорее всего будет >= __PAGE_OFFSET (0xC0000000), то возникнет #PF (как доступ к данным (коду) ring0 из ring3)
Т. е тут прямая зависимость между диапозоном адресов, отводимых под стек (в общем случае под область данных) и "проблемой доступа в не твой регион памяти"

Автор: xni 3.1.2007, 13:11
Согласен, в приложенном сокращении программы ничего происходить не будет... Конечно же там дальше будет цикл, который будет проходиться по всем значениям... Извините, недосмотрел.

А вот насколько я понял - никакие опции компилятора (линкера) не помогут, если в системе программе дается под переменные не более 8Мб. Т.е. манипулировать надо именно с системными настройками. Или я ошибаюсь?

Спасибо за помощь!

Автор: bilbobagginz 3.1.2007, 13:28
в принципе - да.
просто пользователь хотеть всегда может...предполагает, а система определяет и располагает - она знает какое оборудование имеется в распоряжении, какая нагрузка и т.д. и т.п.
обычно в никсах эти настройки стабильны на дистрибутив т.е. конвенция распространяется на дистру.
Есть ведь всякие встроенные устройства, где настройки нужны особые.

а с т.з. системника, есть 2 входных точки - ulimit оболочки или /etc/security/limits.conf

пока.

Автор: JackYF 3.1.2007, 14:18
xni, при твоих 190 - тебе требуется больше 27 Mб стека!
ИМХО просто выделяй память динамически. И все проблемы будут сняты.

Автор: En_t_end 3.1.2007, 16:49
JackYF
Цитата(JackYF @  3.1.2007,  18:18 Найти цитируемый пост)
ИМХО просто выделяй память динамически. И все проблемы будут сняты.

У меня тоже был подобный вопрос в связи с работой на старой системе. Видимо в старых версиях Красной Шляпы стоит слишком заниженное значения для стека, что у меня были проблемы при использовании локальных переменных скалярных типов. Т.е в более упрощенном виде, может возникнуть ситуация, когда просто невозможно будет использовать указатель.

Автор: MAKCim 3.1.2007, 19:07
Цитата

Т.е в более упрощенном виде, может возникнуть ситуация, когда просто невозможно будет использовать указатель. 

это уже почти фантастика  smile 
Цитата

ИМХО просто выделяй память динамически. И все проблемы будут сняты. 

или используй глобальные переменные
Код

static int array[190][190][190] __attribute__((__section__(".bss")));

...

int main() {
...
}

Автор: JackYF 4.1.2007, 15:50
Цитата(MAKCim @  3.1.2007,  19:07 Найти цитируемый пост)
__attribute__((__section__(".bss")));


Это чья примочка? И зачем так сложно?

Автор: MAKCim 4.1.2007, 19:11
Цитата

Это чья примочка? И зачем так сложно?

http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Attribute-Syntax.html#Attribute-Syntax
А сложно, чтобы подчеркнуть, что массив должен лежать в .bss
Естественно можно атрибут не писать
Код

static int array[190][190][190];

Автор: xni 4.1.2007, 22:51
Все. Спасибо всем огромное! Кажется, работает! Мда. Начало программы оказалось не ахти каким приятным  smile  Что же будет дальше? ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)