определение структуры внутри main (), вызывающее ошибку сегментации
Нельзя ли определить структуру внутри main (). Я попробовал следующее только для того, чтобы получить ошибку сегментации:
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1
void main(int argc,char **argv)
{
struct test_struct
{
char test_name[50];
char summary_desc[200];
char result[50];
};
struct suite_struct
{
char suite_name[50];
struct test_struct test[500];
int test_count;
int passed;
int failed;
int unresolved;
int notrun;
}suite[500];
int a,b;
for (a=0;a<500;a++)
{
strcpy(suite[a].suite_name,"");
for (b=0;b<500;b++)
{
strcpy(suite[a].test[b].test_name,"");
strcpy(suite[a].test[b].summary_desc,"");
strcpy(suite[a].test[b].result,"");
}
suite[a].test_count=0;
suite[a].passed=0;
suite[a].failed=0;
suite[a].unresolved=0;
suite[a].notrun=0;
}
}
Но в тот момент, когда я выношу определение структуры за пределы, оно работает:
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1
struct test_struct
{
char test_name[50];
char summary_desc[200];
char result[50];
};
struct suite_struct
{
char suite_name[50];
struct test_struct test[500];
int test_count;
int passed;
int failed;
int unresolved;
int notrun;
}suite[500];
void main(int argc,char **argv)
{
int a,b;
for (a=0;a<500;a++)
{
strcpy(suite[a].suite_name,"");
for (b=0;b<500;b++)
{
strcpy(suite[a].test[b].test_name,"");
strcpy(suite[a].test[b].summary_desc,"");
strcpy(suite[a].test[b].result,"");
}
suite[a].test_count=0;
suite[a].passed=0;
suite[a].failed=0;
suite[a].unresolved=0;
suite[a].notrun=0;
}
}
Не уверен, почему это происходит. Для этого я использую компилятор Solaris SunStudio.
5 ответов:
В первом примере
suite
живет в стеке, а во втором-в сегменте данных.Поскольку
suite
довольно велик (~75 МБ), segfault почти наверняка вызвано тем, что ваша программа исчерпала пространство стека.В большинстве случаев лучше всего выделить большие структуры данных в куче (используя
malloc()
и др.). Это также позволит выделить только то количество пространства, которое вам требуется, вместо того, чтобы всегда выделять пространство для 500 элементов.
Можно объявить структуру внутри main. Но в вашей программе проблема связана с тем, что вы создаете 500 объектов этой структуры внутри основной функции. Каждый объект имеет размер около 15 КБ. Итак, 500 объектов требуют около 75 Мбайт. Попробуйте
printf("size: %lu\n", sizeof suite);
.У вас не так много стека, доступного по умолчанию. Вы можете найти доступный стек, используя команду
ulimit -s
. Он печатает доступный стек в KBs.Вы можете использовать команду
ulimit
для увеличения стек. например,ulimit -s 100000
.Лучший подход заключается в динамическом выделении требуемой памяти с помощью
malloc()
.
Законно определить
Но код может быть синтаксически законным и аварийно завершаться во время выполнения (например, потому, что он имеет неопределенное поведение, согласно стандарту C, или потому, что он сталкивается с некоторыми системными ограничениями, такими как ограничение на стек вызовов).struct
и объявить локальную переменную этогоstruct
внутри любой функции, включаяmain
.
Структура, которую вы определяете вне main, является глобальной и неинициализированной, поэтому она войдет в структуру .сегмент bss и инициализируется до 0 в начале выполнения. Структура, которую вы определяете внутри main, огромна и превышает максимальный размер стека (который составляет около 1-2 МБ в Linux и, вероятно, Solaris тоже). Поскольку один из них вне main не находится в стеке, он, по-видимому, работает в этом случае, а не в другом.
В дополнение к ответам о пространстве стека, malloc и неопределенном поведении . . .
Когда я попытался скомпилировать ваш код, я получил 3 предупреждения.
test.c:7:6: warning: return type of ‘main’ is not ‘int’ test.c: In function ‘main’: test.c:32:17: warning: implicit declaration of function ‘strcpy’ test.c:32:17: warning: incompatible implicit declaration of built-in function ‘strcpy’
Возвращает int для main, а не void.
int main(int argc,char **argv)
В языке C заголовок strcpy-string.h, не струны.h.