-2

私の主な意図は、メモリを割り当ててそのすべての値を埋める構造体、関数へのポインタを渡すことです。戻った後、画面に印刷します。

構造はこんな感じ。

struct isolock{
    char *name;
    unsigned int state;};
typedef struct isolock lock;

この構造体の宣言は変更できないことに注意してください。私の主な機能は、このように非常に単純です。

int main(){
    int i = 0;
    isolock *lock = NULL;
    fillArray(&lock);

    //print struct contents
    for(i=0;(lock+i)->name;i++){
            printf("name = %s status = %u \n", (lock+i)->name,(lock+i)->state);
    }

}

fillArray 関数は、構造体に n + 1 メモリ ブロックを割り当てると想定しています。ここで、n は、存在するロックの実際の数です。一方、最後の (n+1) 番目のブロックはゼロで埋められます。そのため、メインから印刷しているときに、割り当てた構造体の長さを気にする必要なく、この状態を確認できます。

私の問題はfillArray関数にあります。

static const char *array[] = {"SWMGMT_LOCK","OTHER_LOCK"};
void fillArray(isolock **dlock){
    int i = 0;
    if (*dlock == NULL){
            *dlock = (isolock *)malloc((sizeof (*dlock)) * 3);      //allocate space for holding 3 struct values

            for(i=0;i<2;i++){
                    (*(dlock) + i)->name = strdup(array[i]);       
                    (*(dlock) + i)->state = (unsigned int)(i+1);                                           
            }
            (*(dlock) + i)->name = 0;   //LINE100
            (*(dlock) + i)->state = 0;
    }
}
o/p:

name =  status = 1 
name = OTHER_FP_LOCK status = 2 

実はこのLINE100が問題を起こしています。実際には、すでに埋められている構造体のエントリを置き換えます。つまり、この行は dlock[0]->name を 0 で埋めます。一方、dlock[1] は変更されません。

私のgdbログはこのようなものを示しています.

これらはすべて、割り当てと値の入力後に取得されるログです。

    (gdb) p (*(dlock)+0)
    $10 = (isolock *) 0x804b008
    (gdb) p (*(dlock)+1)
    $11 = (isolock *) 0x804b010 
    (gdb) p (*(dlock)+2)                      <== Note here 1
    $12 = (isolock *) 0x804b018
    (gdb) p *(*(dlock)+0)
    $13 = {name = 0x804b018 "SWMGMT_LOCK", state = 1}     <== Note here 2
    (gdb) p *(*(dlock)+1)
    $14 = {name = 0x804b028 "OTHER_FP_LOCK", state = 2}
    (gdb) n
    33    (*(dlock) + i)->state = 0;
    (gdb) 
    35   }
    (gdb) p *(*(dlock)+2)
    $15 = {name = 0x0, state = 0}
    (gdb) p (*(dlock)+2)
    $16 = (isolock *) 0x804b018

メモ 1 とメモ 2 から、strdup が malloc によって既に割り当てられているメモリ位置を返したこと、つまり、strdup への最初の呼び出しが dlock[2] のアドレスを返したことは明らかです。どうしてこうなった。このため、 (*dlock+2)->name = 0 により dlock[0]->name が 0 で埋められました。

この問題を簡単に説明すると、Malloc は 3 つのアドレスを返してきました。簡単に理解できるように、{1000,1008,1010} としましょう。{1010,1018} を返す strdup を 2 回呼び出しました。

この 1010 と 1018 は、それぞれ char *name of lock[0] と lock[1] に格納されます。

誰かが私に教えてくれますか、私はこのコードで何か間違ったことをしていますか、それとも strdup の問題ですか (既に割り当てられたメモリブロックを割り当てています)

注: char *name を char name[20] に変更し、strdup の代わりに strcpy を使用すると、完全に機能しました。

4

1 に答える 1

2

エラーの考えられる原因は、割り当てです。

*dlock = (isolock *)malloc((sizeof (*dlock)) * 3);

これがdlockポインタへのポインタであるため、 (または)sizeof(*dlock)と同じではないポインタのサイズも同様です。sizeof(struct isolock)sizeof(**dlock)

于 2012-09-15T12:21:53.693 に答える