2012-01-25 3 views
3

Невозможно определить структуру внутри main(). Я попытался следующие только получить Segmentation Fault:определение структуры внутри 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.

+10

'void main' ** RAAAAAARRRRRRGGGGGGHHHHH! ** – pmg

+1

Вы действительно должны ** научиться использовать отладчик **. Вы пытались скомпилировать свою программу с включенными предупреждениями и информацией об отладке (с 'gcc', что означает' -Wall -g')? Вы использовали отладчик? Мы могли бы найти вашу ошибку, но вы действительно должны научиться самостоятельно отлаживать .... –

+2

void main является незаконным. Структуры кажутся Ок. Но они довольно большие для автоматического хранения. – wildplasser

ответ

6

В первом примере suite живет в стеке, а во втором он живет в сегменте данных.

С suite довольно большой (~ 75 МБ), segfault почти наверняка объясняется тем, что ваша программа заканчивается из пространства стека.

В большинстве случаев лучше всего выделить большие структуры данных в куче (используя malloc() и др.). Это также позволит выделить всего необходимое пространство, а не выделять пространство для 500 элементов.

+0

Есть ли способ увеличить пространство в стеке? – tomkaith13

+2

@ tomkaith13 это неправильный вопрос. Определите структуры вне 'main()' или в файле заголовка и выделите место в куче для них с помощью 'malloc()'. –

+0

@aix: Я собирался опубликовать одно и то же, а затем неправильно понял ваше имя пользователя как мое и имел полный момент WTF. – arx

3

Это нормально объявить структуру внутри основного. Но в вашей программе проблема связана с тем, что вы создаете 500 объектов этой структуры внутри основной функции. Каждый объект имеет размер около 15 КБ. Таким образом, 500 объектов требуют около 75 МБ. Попробуйте printf("size: %lu\n", sizeof suite);.

По умолчанию у вас не так много стека. Вы можете найти доступный стек, используя команду ulimit -s. Он печатает доступный стек в КБ.

Чтобы увеличить стек, вы можете использовать команду ulimit. например ulimit -s 100000.

Лучшим подходом является динамическое распределение требуемой памяти с использованием malloc().

1

Законно определять struct и объявлять локальную переменную этого struct внутри любой функции, включая main.

Но код может быть синтаксически законным и сбой во время выполнения (например, поскольку он имеет неопределенное поведение в соответствии со стандартом C или потому, что он затрагивает некоторые системные ограничения, такие как ограничение на стек вызовов).

1

Структура, которую вы определяете вне main, является глобальной и неинициализированной, поэтому она войдет в сегмент .bss и будет инициализирована до нуля в начале выполнения. Структура, которую вы определяете внутри основного, огромна и превышает максимальный размер стека (примерно 1-2 МБ на Linux и, возможно, Solaris). Так как один за пределами основного не находится в стеке, он, похоже, работает в этом случае, а не другой.

+0

Размер стека по умолчанию на SuSE равен 8192K. Тем не менее, далеки от необходимости ~ 75M. –

+0

На самом деле, похоже, я думал о Windows для 1-2 МБ – arsenm

1

В дополнение к ответам о пространстве стека, 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 для основного, непустого.

int main(int argc,char **argv) 

В C заголовок для strcpy - string.h, а не strings.h.