私の主な意図は、メモリを割り当ててそのすべての値を埋める構造体、関数へのポインタを渡すことです。戻った後、画面に印刷します。
構造はこんな感じ。
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 を使用すると、完全に機能しました。