Définition de structure à l'intérieur de Main () provoquant une défaut de segmentation

StackOverflow https://stackoverflow.com/questions/9007773

Question

N'est-il pas possible de définir la structure à l'intérieur de Main (). J'ai essayé ce qui suit pour obtenir un défaut de segmentation:

#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;
        }
}

Mais au moment où je prends la définition de structure à l'extérieur, cela fonctionne:

#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;
        }
}

Je ne sais pas pourquoi cela se produit. J'utilise le compilateur Solaris Sunstudio pour cela.

Était-ce utile?

La solution

Dans le premier exemple, suite vit sur la pile et, dans la seconde, il vit sur le segment des données.

Depuis suite est assez grand (~ 75 Mo), la segfault est presque certainement due à votre programme à court d'espace de pile.

Dans la plupart des cas, il est préférable d'allouer de grandes structures de données sur le tas (en utilisant malloc() et al). Cela permettra également d'allouer uniquement la quantité d'espace dont vous avez besoin au lieu de toujours allouer de l'espace à 500 éléments.

Autres conseils

Il est normal de déclarer une structure à l'intérieur de Main. Mais dans votre programme, le problème a à voir avec le fait que vous créez 500 objets de cette structure dans la fonction principale. Chaque objet a une taille d'environ 15 Ko. Ainsi, 500 objets nécessitent environ 75 Mo. Essayer printf("size: %lu\n", sizeof suite);.

Vous n'avez pas beaucoup de pile disponibles par défaut. Vous pouvez trouver la pile disponible en utilisant la commande ulimit -s. Il imprime la pile disponible dans KBS.

Vous pouvez utiliser le ulimit commande pour augmenter la pile. par exemple ulimit -s 100000.

Une meilleure approche consiste à allouer dynamiquement la mémoire dont vous avez besoin malloc().

Il est légal de définir un struct et pour déclarer une variable locale de cela struct Dans n'importe quelle fonction, y compris main.

Mais un code peut être syntaxiquement légal et s'écraser au moment de l'exécution (par exemple parce qu'il a un comportement non défini, selon la norme C, ou parce qu'il atteint une limitation du système, comme une limite sur la pile d'appels).

La structure que vous définissez en dehors de la main est globale et non initialisée afin qu'elle entrera dans le segment .bss et sera initialisée à 0 au début de l'exécution. La structure que vous définissez à l'intérieur de la main est énorme et dépasse la taille maximale de la pile (qui est d'environ 1 à 2 Mo sur Linux et probablement aussi Solaris). Étant donné que l'un en dehors de la main n'est pas sur la pile, cela semble fonctionner dans ce cas et non l'autre.

En plus des réponses sur l'espace de pile, le malloc et le comportement non défini. . .

Lorsque j'ai essayé de compiler votre code, j'ai obtenu 3 avertissements.

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’

Renvoyez un INT pour Main, pas vide.

int main(int argc,char **argv)

En C, l'en-tête de Strcpy est String.h, pas Strings.h.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top