2012-03-16 24 views
1

LinuxでXScale(arm v5te)システムで実行されている従来のコードをデバッグしていましたが、再現性がありません。ポインタを無効にするポインタの配列が無効です

私はそれはとてもちょうどいくつかのスニペット、コードの多くのですGDBを使用してデバッグし、1にMALLOC_CHECK_を設定している

私たちは、このような構造を持っている:

typedef struct { 
...clipped.. 
    char **data_column_list; 
    /** data column count */ 
    int data_column_cnt; 
...clipped 
} csv_t; 

我々は、機能の列を初期化します

:変数「列」、別の関数で

/* Allocating memory for pointer to every register id */ 
columns = (char **) malloc(column_cnt * sizeof(char *)); 

column_cnt = 0; 
/* loop over all sensors */ 
for(i=0; i<cfg.sen_cnt; i++) { 
    /* loop over all registers */ 
    for(j=0; j<cfg.sen_list[i]->data_cnt; j++) { 
     /* Storing all the pointers to id */ 
     columns[column_cnt++] = cfg.sen_list[i]->data_list[j]->id; 
    } 
} 

でそれらを入れて、何が起こるかは、このです

/* free the previous list */ 
csv_free(lc_csv); 

lc_csv->data_column_list = columns; 
lc_csv->data_column_cnt = column_cnt; 

csv_freeのビーイング:

void csv_free(csv_t *csv) { 
    if(csv->data_column_cnt > 0) 
     free(csv->data_column_list); 

    csv->data_column_cnt = 0; 
} 

は今、これらのIDが含まれています全体の "CFG"/configの構造を、構築し、別の関数があります。 コードfrome:cfg.sen_list [i] - > data_list [j] - > id; cfgは構造体、sen_listは構造体へのポインタ配列、data_listは文字列 "id"を含む他の構造体へのポインタの配列です。

プログラムが信号SIGUSR1を取得すると、設定が更新されています。これらのdata_listとsen_list構造体はすべて解放され、新しいものが生成されます。 最初の関数では、idの新しいcollumnが生成され、csv構造体に入れられますが、以前のリストは解放されています。

それはクラッシュします。 csv_freeで。

*** glibc detected *** /root/elv: free(): invalid pointer: 0x0001ae88 *** 

私はこのようにすべきだと思いました。あなたはポインタの配列を持っています。ポインタを解放すると、ポインタを解放してポインタのセット(配列)を指し示す必要があります。 またはコード用語で言えば、上記の状況は、アナログ - する必要があります:構造体は、IDの文字列を含む、解放されたとき、私はまだ(無効)のポインタ、NOT NULLポインタで私のポインタの配列を持っている

char **ar = malloc(n * sizeof(char *)); 
char *xn = malloc(10 * sizeof(char)); // Do for 0 to n strings 
... 
ar[n] = xn; // Do for 0 to n strings 
...do stuff... 
free(xn); // Do for 0 to n strings 
free(ar); 

(gdb) p csv 
$40 = {sysid = 222, ip = '\0' <repeats 49 times>, 
    module = "elv_v2", '\0' <repeats 14 times>, format_type = 1, msg_id = 0, 
    data_column_list = 0x1ae88, data_column_cnt = 10, pub_int = 30, 
    line_cnt = 0, pub_seq = -1, format = 0x18260} 
(gdb) p csv.data_column_list[0] 
$41 = 0x1b378 "0" 

しかし、上記のエラーメッセージ(またはMALLOC_CHECK_がないSIGABRT)が表示されます。 私はこれを全く理解していません。私はポインタのこの配列を解放する必要があります、またはそれはメモリリークになります。私が見つけることができるそれの前に無料の他の呼び出しはありません。なぜ私はcsv.data_column_listが無効なポインタと見なされるのか分かりません。 。

: Valgrindのは、残念ながら腕v5te :(

にavailiable時間と時間のためにこれをデバッグされており、任意の助けのために幸せになる は非常に多く、 乾杯、 ベン

UPDATEありがとうではありません

私はそれがいくつかの "スコープ"の問題​​に接続できるかどうか疑問に思っています。別のアプリケーションにはほとんど同じコードがあります。唯一の違いは、解放されるポインタを含む構造体が宣言され、正常に動作プログラムで定義され、externalと宣言され、main.c以外のファイルで定義されていることです。 main.cで "free" "csv_free"がクラッシュします。私は自由に実行したときにエラーが実際に割り当てまたは初期化で始まった問題)(この... 10回のうち

+3

valgrindで実行してみましたか? –

+1

mallocsの直後と解放の直前にブレークポイントを設定した場合、すべてのポインタ値が一致しますか? –

+0

あなたは 'csv'が' csv_free'に 'NULL'かどうかをチェックし、' csv'を解放した後にNULLを割り当てるべきです。これは、 'csv'がNULLまたは何らかのゴミであるときに' csv-> member'を実行するのを防ぎます。 – phoxis

答えて

0

。私はもうその会社で働いていないので、実際に確認することはできませんが、私たちが持っていた他の問題を考えると、私はワイルドプラッサーが正しいと思います。

シグナルハンドラ内から大きな関数を呼び出すことは悪い考えです。特に、あなたがしていることがすべてリエントラントであるかどうかチェックしていなければ。それはレガシーコードなので、少なくとも完全に私のせいではありません;)

今日、シグナルハンドラでフラグを設定し、そのフラグがセットされているときにメインループでルーチンを呼び出します。

0

9私をRIDDLE、それでは、そのビットを確認してみましょう:

あなたは
  1. 実際にcolumnscsv.data_columns_listを割り当てます。の前にcsv_freeと電話をかけますか?あなたがfree()のときに初期化されていなければ、エラーを説明します。 2番目のコードブロックで

  2. 、初期column_cnt(私は他の場所で に設定されている推測?)あなたは アレイの外側に書くことになりループの後column_cnt未満の場合。一つはMALLOC_CHECK_がそれをキャッチします願っていますが、何を と主張した場合に起こることは、以下になります。

    私はこれを見た私の古い質問を見ている
    /* Allocating memory for pointer to every register id */ 
    columns = (char **) malloc(column_cnt * sizeof(char *)); 
    
    int old_column_cnt = column_cnt; 
    column_cnt = 0; 
    /* loop over all sensors */ 
    for(i=0; i<cfg.sen_cnt; i++) { 
        /* loop over all registers */ 
        for(j=0; j<cfg.sen_list[i]->data_cnt; j++) { 
         /* Storing all the pointers to id */ 
         columns[column_cnt++] = cfg.sen_list[i]->data_list[j]->id; 
        } 
    } 
    assert(old_column_cnt >= column_cnt); 
    
関連する問題