2

基本的に次のようなプログラムがあります。

    typedef struct cpl_def
            {
            int A;
            int B;
            int OK; 
            struct cpls *link;  
            }cpls;


        int main(void)
            {
            int n1, n2;
            int num = 300; /* say */
            int *a;
            a = NULL;
            int *apt;

            int *b;
            b = NULL;
            int *bpt;

            cpls *cplptr; 
            cplptr = NULL; 

                int i, j;
                for (i=0; i < 2000; i++) 
                    {

                    if (i == 0)
                        {
                        cplptr = (cpls *) malloc(num*sizeof(cpls) ); /* create the structure */ 
                        initalize(cplptr);
                        }
    /*
                    ...operations on cplptr ...  */  


                   FOO(cplptr);
     /*
               ...determine I need a subset of size n1 (a positive integer of size n1 which changes during the loop) entries from cplptr ...  */

                 n1 = FOO2(cplptr);
                 n2 = FOO3(cplptr);

 /*
               ...figure out the values of A, B for additional n2 entries into cplptr ...
      */        
    cplptr2 = (cpls *) malloc(n2*sizeof(cpls) ); /* a second structure to store additional entries */
            /* .... operations on cplptr2 ...*/

    /* ...copy subset of n1 entries from cplptr into dynamically allocated arrays a,b of size n1... */  

            a = malloc(n1 * sizeof(int));
            apt = &a[0];

            b = malloc(n1 * sizeof(int));
            bpt = &b[0];


            for (j=0; j < num; j++)
                 {
                 if (cplptr[j].OK==1)
                            {
                            (*apt++) = cplptr[j].a;
                            (*bpt++) = cplptr[j].b;
                            }
                 }
               free(cplptr); /* free the first structure */

               cplptr = (cpls *) malloc((n1+n2)*sizeof(cpls) ); /* redeclare the first structure to reflect the proper sizes */

               for (j = 0; j < n1; j++) /* transfer a subset of size n1 to the first structure */
                      {
                       cplptr[j].a = a[j];
                       cplptr[j].b = b[j];
                       cplptr[j].OK = 1;
                      }
               for (j = n1; j < n1 + n2; j++) /* transfer things to the first structure */
                      {
                       cplptr[j].a = cplptr2[j].a;
                       cplptr[j].b = cplptr2[j].b;
                       cplptr[j].OK = cplptr2[j].OK;
                      }

               free(a)
               free(b)

               free(cplptr2); /* free the second structure */
             } /* End iteration i
    } /* End main() */

これは単なる骨格ですが、うまくいけば十分な画像が得られます. A とにかく、通常は正常に動作しますが、n1、n2 の一部の値では、free(cplptr) がセグメンテーション違反を引き起こすようです。これは 1 回だけ呼び出され、cplptr への malloc() 呼び出しの後、cplptr の対応する free() の前にアドレスをチェックします。

.... 
cplptr = (cpls *) malloc(num*sizeof(cpls) );
printf("fine to this %p\n", &cplptr[0]);
...
printf("fine to this %p\n", &cplptr[0]);
free(cplptr) <- segmentation fault happens here.

アドレスが一致しているということは、free() が解放すべきものを解放しているということですよね?? gdb は、プログラムが受信したシグナル SIGSEGV、セグメンテーション違反を示します。0xb7ce179b in ?? () /lib/tls/i686/cmov/libc.so.6 およびステップから 現在の関数の境界が見つかりません

セグメンテーション違反を回避するようなものを実装する別の方法はありますか?

あなたの提案をありがとう!何が起こっているのか分かりますか??

4

7 に答える 7

3

free() でクラッシュが発生している場合、これはヒープの破損が原因である可能性が最も高く、割り当てられたメモリ ブロックの末尾を超えて書き込みを行っているか、ポインターを 2 回解放しているなどです。

Valgrindは、Linux でこの種の問題をデバッグするための優れたツールです。

于 2009-06-28T00:27:16.143 に答える
1
for (j = n1; j < n1 + n2; j++) /* transfer things to the first structure */
{
      cplptr[j].a = cplptr2[j].a;
      cplptr[j].b = cplptr2[j].b;
      cplptr[j].OK = cplptr2[j].OK;
} 

ここでは、cplptr2 の index(j) に n1 から n1 + n2 にアクセスしていますが、割り当てに従ってcplptr2 = (cpls *) malloc(n2*sizeof(cpls))、インデックスは 0 から n2-1 に移動する必要があります。cplptr2 には j の代わりに j-n1 を使用することをお勧めします。

于 2011-08-04T09:22:31.077 に答える
1

これから、リンクされたリストを作成しようとしているように見えます:

typedef struct cpl_def
{
  int A;
  int B;
  int OK; 
  struct cpls *link;      
} cpls;

しかし、それを使用する方法では、配列を作成しています。

cplptr = (cpls *) malloc(num*sizeof(cpls) );
...
cplptr[j].a = a[j];

これは、あなたが本当にやろうとしていることを私には不明確にします。メンバーも初期化していないように見えるlinkので、リンクされたリストのように扱い、最後からハイパースペースに入ろうとしている可能性がありますか?

あなたのコードから私には奇妙に見える他のもの:

  1. n1n2値を受け取ることはありません
  2. apt変数を何にも使用していないようです
  3. aそしてb決して解放されない
  4. からの戻り値をチェックしていmallocません。割り当てに失敗している可能性がありますか?

ただし、これは実際には「喫煙銃」ではありません。サンプルを機能するものに絞り込む必要がありますが、それでも問題は発生しますか?

于 2009-06-28T00:35:56.143 に答える
1

フラグを設定する

投稿する前に、次のフラグを設定することを検討してください: cc -Werror -Wall smth.c

smth.c: In function 'main':
smth.c:13: error: 'NULL' undeclared (first use in this function)
smth.c:13: error: (Each undeclared identifier is reported only once
smth.c:13: error: for each function it appears in.)
cc1: warnings being treated as errors
smth.c:29: warning: implicit declaration of function 'malloc'
smth.c:29: warning: incompatible implicit declaration of built-in function 'malloc'
smth.c:37: error: 'cplptr2' undeclared (first use in this function)
smth.c:37: warning: incompatible implicit declaration of built-in function 'malloc'
smth.c:53: error: 'struct cpl_def' has no member named 'a'
smth.c:54: error: 'struct cpl_def' has no member named 'b'
smth.c:57: warning: implicit declaration of function 'free'
smth.c:63: error: 'struct cpl_def' has no member named 'a'
smth.c:64: error: 'struct cpl_def' has no member named 'b'
smth.c:69: error: 'struct cpl_def' has no member named 'a'
smth.c:70: error: 'struct cpl_def' has no member named 'b'
smth.c:76:12: error: "/*" within comment
smth.c:77: warning: control reaches end of non-void function

次に必要なのは動的配列 です コードを構造化してください! このような配列を構築する関数は抽象化できます。

右から左に読みますか?問題はありませんが、コメントはコードの前に置きます。

/* comment */
code

スタープログラマーになるな!複数の星が必要な場合は、関数を作成します。

于 2009-06-28T01:06:00.387 に答える
0

実際のプログラムでは、n1 と n2 をどこかに設定していると思いますか?

また、i==0 をチェックする代わりに、ループの外側に cplptr を割り当てます。

タイプミスがあるかもしれません.bptを設定していませんが、aptを2回設定しています.

于 2009-06-28T00:32:27.617 に答える
0

n1 または n2 をどこにも初期化していません。それらはゼロまたは負でさえある可能性があります。

于 2009-06-28T00:33:52.963 に答える
0
  a = malloc(n1 * sizeof(int));
  apt = &a[0];

  b = malloc(n1 * sizeof(int));
  apt = &b[0]; // <-- should be bpt, bug ?
于 2009-06-28T00:34:52.993 に答える