3

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 コンパイラを使用しています。

4

5 に答える 5

6

最初の例でsuiteはスタックに存在し、2 番目の例ではデータ セグメントに存在します。

は非常に大きい (~75MB)ためsuite、segfault はほぼ確実に、プログラムのスタック領域が不足していることが原因です。

ほとんどの場合、( malloc()et al を使用して) ヒープに大きなデータ構造を割り当てるのが最善です。これにより、常に 500 個の要素にスペースを割り当てるのではなく、必要な量のスペースだけを割り当てることも可能になります。

于 2012-01-25T18:08:51.720 に答える
3

main 内で構造体を宣言しても問題ありません。しかし、あなたのプログラムでは、メイン関数内にその構造の 500 個のオブジェクトを作成しているという事実に問題があります。各オブジェクトのサイズは約 15 KB です。したがって、500 個のオブジェクトには約 75 MB が必要です。試してみてくださいprintf("size: %lu\n", sizeof suite);

デフォルトでは、利用可能なスタックはそれほど多くありません。コマンドを使用して、利用可能なスタックを見つけることができますulimit -s。利用可能なスタックを KB 単位で出力します。

コマンドを使用しulimitてスタックを増やすことができます。例えばulimit -s 100000

より良いアプローチは、必要なメモリを動的に割り当てることですmalloc()

于 2012-01-25T18:10:37.243 に答える
1

を定義し、 を含む任意の関数内structでそのローカル変数を宣言することは合法です。structmain

しかし、コードは構文的に正当であり、実行時にクラッシュする可能性があります (たとえば、C 標準に従って未定義の動作があるため、またはコール スタックの制限などのシステム制限に達したため)。

于 2012-01-25T18:13:45.137 に答える
1

main の外で定義する構造体はグローバルで初期化されていないため、.bss セグメントに入り、実行の開始時に 0 に初期化されます。main 内で定義する構造体は巨大で、最大スタック サイズを超えています (Linux では約 1 ~ 2MB、おそらく Solaris も同様です)。メインの外側のものはスタック上にないため、その場合は機能するように見えますが、他の場合は機能しないようです。

于 2012-01-25T18:18:58.110 に答える
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’

void ではなく、main の int を返します。

int main(int argc,char **argv)

C では、strcpy のヘッダーは string.h であり、strings.h ではありません。

于 2012-01-25T18:19:28.533 に答える