LINUX.ORG.RU

char line[VERY_BIG] + malloc() = SIGSEGV


0

2

Всем доброго времени суток!

собственно код:

#include <stdlib.h>

#define VERY_BIG 1024*1024*1024 

int main (void)
{
	char line[VERY_BIG];
	char *p;

	p = (char*)malloc(1);
	free(p);

	return 0;
}

Получаю SIGSEGV на маллоке, когда BIG больше некоторого значения. На разных ОС предельное значение разное. CPUx86, gcc4

И собственно вопросы: 1) Почему? 2) Где про это читать?

UP: Спасибо всем огромное, проблему понял. Массив line[VERY_BIG] съедает стек.

С проблемой столкнулся в проекте под QNX6. Там код далеко не такой игрушечный но суть та же.

PS: Первый раз пишу на ЛОР. В шоке от оперативности. Очень тронут. Всем еще раз спасибо.



Последнее исправление: solo1h (всего исправлений: 3)

я не сишник, но подозреваю, что размер выделяемого пространства для программы ограничен. Как минимум 32х разрядной адресацией. Скорее всего чем-то еще. Ну а вообще скорее всего у вас просто не хватает памяти+свопа чтобы выделить гиг памяти.

JFreeM ★★★☆
()

ты гиг памяти аллоцируешь в стеке, вот его и выносит. Лимит стека по умолчанию, ЕМНИП, несколько мегабайт, максимум несколько десятков

marvin_yorke ★★★
()
Ответ на: комментарий от metawishmaster

речь вроде про VERY_BIG в заголовке. и

когда BIG больше некоторого значения

аффтар, где опечатка?

marvin_yorke ★★★
()
Ответ на: комментарий от solo1h

Ваш line вообще оптимизатором выбрасывается, как неиспользуемый, давайте сразу рабочий код , а то учебный больше запутывает :)

ilovewindows ★★★★★
()
Ответ на: комментарий от solo1h

ну значит я прав.
char line[VERY_BIG] аллоцируется на стеке, как локальная переменная (если конечно не выбрасывается оптимизатором, покажи какой командой компилируешь) и при слишком большом размере оный стек сносит

marvin_yorke ★★★
()

на моей 32х-битной машинке вот таое сейчас с памятью:

             total       used       free     shared    buffers     cached
Mem:       1554012    1517488      36524          0      83484    1034388
-/+ buffers/cache:     399616    1154396
Swap:      1566300      20016    1546284

при этом исходник в заголовке нормально отрабатывает (если викинуть BIG).

есть подозрение, что память на машине ТС фрагментирована....

metawishmaster ★★★★★
()

а таки marvin_yorke прав.

стеки всегда и везде были очень маленькими - даже рекурсивные вызовы функций из-за этого не поощраются

metawishmaster ★★★★★
()

размер стека сильно ограничен, выделяй на куче. Почитать про это в гугле по «C storage classes». Там были всякие auto, heap, register, static и всё такое.

true_admin ★★★★★
()
Ответ на: комментарий от anonymous

На стеке alloca выделяет.

на стеке выделяется всё что auto

true_admin ★★★★★
()
Ответ на: комментарий от marvin_yorke

c -O2 тот же SIGSEGV...

Но мысль на счет стека понял, спасибо.

solo1h
() автор топика

#define VERY_BIG 1024*1024*1024 вообще-то запросто может и урезаться до и 16 битового , лучше писать множители как 1024L или (unsigned long)1024 или сразу 0x40000000 писать

ilovewindows ★★★★★
()
p = (char*)malloc(1);
if(p)	free(p);
RETURN VALUE
       The malloc() and calloc() functions return a pointer to  the  allocated
       memory  that  is  suitably aligned for any kind of variable.  On error,
       these functions return NULL.

а на вопрос «почему» ответит errno и остальные вызовы для диагностики ошибок

aol ★★★★★
()

Переменная line занимает весь стек и ещё под ним «чужую» память. Переменная p лежит под line, т.е. ещё глубже в «чужой» памяти. При попытке записи указателя (вполне хорошего), который вернула malloc, в эту переменную и случается сабжевый сегфолт.

Такой же сегфолт должен случиться, если вместо вызова malloc сделать просто

line[0] = 'Q';

const86 ★★★★★
()
Ответ на: комментарий от const86

Случится и в таком случае

#include <stdlib.h>
#define VERY_BIG 1024*1024*1024 

void foo( void )
{
}

int main (void)
{
	char line[VERY_BIG];

	foo();

	return 0;
}

anonymous
()
Ответ на: комментарий от const86

А может, для вызова malloc() стека уже не хватает?

ТС, ты попробуй любую другую функцию вызвать.

r2d2
()

Это не на маллоке, а на попытке из кучи выделить гигабайт памяти. Вот фигвам и получается.

А вот так

#include <stdlib.h>

#define VERY_BIG 1024*1024*1024 

int main (void)
{
	char line = malloc(VERY_BIG);
	char *p;

	p = (char*)malloc(1);
	free(p);

	return 0;
}
все ОК

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от marvin_yorke

Да, Вы как про стек изволили сказать, до меня сразу дошло. Спасибо еще раз.

solo1h
() автор топика

Потому что ты память похерил вот этой char line[VERY_BIG]; строчкой. В стэк 1024*1024*1024 не влезет никак.

invy ★★★★★
()
Ответ на: комментарий от const86

Такой же сегфолт должен случиться, если вместо вызова malloc сделать просто

line[0] = 'Q';

может и не случится, кто знает куда line указывает. У меня такие приколы были.

true_admin ★★★★★
()

ты не на маллоке получаешь SIGSEGV

Reset ★★★★★
()
Ответ на: комментарий от ilovewindows

#define VERY_BIG 1024*1024*1024 вообще-то запросто может и урезаться до и 16 битового

При 32-битном int влезет согласно стандарту.

Pavval ★★★★★
()

char line[VERY_BIG]; - выделяет память на стеке, эту самую память никак не трогая - по сути, просто уменьшает esp, после этого esp уже указывает на память вне стека char *p - аналогично

а вот присвоение p - это уже обращение по адресу esp и, соответственно, segfault.

Нет, оптимизации тут не при чём, и нет, в malloc(1) проблемы нет.

slovazap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.