Переполнение стека (0xC00000fd) при заполнении аргумента массива, но не при заполнении статического массива

#c

#c

Вопрос:

Отказ от ответственности: я новичок в C.

Я написал программу для генерации набора случайных чисел в нормальном распределении со средним mean значением и стандартным отклонением stddev . Числа помещаются в массив r . Количество генерируемых случайных чисел задается константой NUMRANDOMS .

Я написал функцию getRandom , которая передается mean и stddev . Он создает случайные числа и помещает их в r .

Я написал две версии getRandom . Первая версия создается r как статический массив и возвращает указатель на r :

 double * getRandom(double mean, double stddev) {
    static double r[NUMRANDOMS];

    for (int i = 0; i < NUMRANDOMS; i  ) {
        r[i] = normal(mean, stddev);
    }
    return r;
}
 

Эта версия работает идеально, независимо от того, какой размер я установил NUMRANDOMS . Я поднялся до 100 миллионов, и он работает идеально.

Для второй версии getRandom я передаю ему массив r и длину массива (т.Е. NUMRANDOMS ):

 void getRandom(double r[], int len, double mean, double stddev) 

    for (int i = 0; i < len; i  ) {
        r[i] = normal(mean, stddev);
    }
    return;
}
 

Эта версия отлично работает для NUMRANDOMS значений 1000, 10000 или 100 000, но когда я устанавливаю его равным одному миллиону, я получаю ошибку времени выполнения 0xC00000fd . Из других сообщений я узнал, что это сообщение об ошибке означает «переполнение стека».

Почему вторая версия работает нормально, пока не достигнет одного миллиона? Почему первая версия работает нормально даже со 100 миллионами?

Комментарии:

1. Как распределяется массив во второй версии?

Ответ №1:

Скорее всего, вы выделяете r в стеке в вызывающем объекте, например:

 double r[NUMRANDOMS];
getRandom(r, NUMRANDOMS, ...);
 

В то время как в первой версии у вас это как static :

 static double r[NUMRANDOMS];
 

В этой последней версии память резервируется операционной системой при загрузке программы.

Стек в типичных операционных системах по умолчанию довольно мал (например, 1 МБ). Напротив, разделы BSS / data обычно имеют ограничение на порядок выше.

Комментарии:

1. Да, для обеих учетных записей. Фантастика! Спасибо @Acorn