2012-10-02 42 views
2

我有一個表示在一個表中的行的結構:添加指針動態指針陣列中的一個環在C

typedef struct { 
    char *a; 
    char *b; 
} row; 

和我有初始化基於分貝數據行,並返回一個指針的函數它

row* get_row(dbrow d) { 
    row *r = malloc(sizeof(row)); 
    r->a = malloc(5); 
    strcpy(r->a, d.a); 
    r->b = malloc(5); 
    strcpy(r->b, d.b); 
    return r; 
} 

終於,我有了一個row **rows作爲參數的函數:

void get_rows(row **rows) { 
    ... 
    rows = malloc(rowNumber * sizeof(row*)); 
    int i; 
    for (i = 0; i < rowNumber; i++) { 
     rows[i] = get_row(dbrow); 
    } 
} 

get_row按預期工作,並返回一個指向有效行結構的指針,但gdb顯示行[0](以及所有其他行)永遠不會獲得新值,也就是說它總是指向相同的地址,就好像rows[i] = get_row(dbrow)行不存在。

+0

'rowNumber'從哪裏來?你可以發佈你的整個代碼嗎? –

+0

rowNumber被初始化爲1.周圍的代碼處理數據庫訪問,有點麻煩,它的工作原理,它確實對所示的代碼有影響。直到指針分配的所有內容都應該如此。 – cbaby

回答

5

... GDB顯示的行[0](和所有其他人)從來沒有得到一個新的價值...

我在此假設您正在尋找的返回值您的get_rows函數,而不是其局部變量rows的值。這裏的問題是:

rows = malloc(rowNumber * sizeof(row*)); 

您分配一個新值複製收到的功能,而不是原來的原始指針。這個改變在函數外部是不可見的。

如果你需要一個新的值賦給參數,那麼你將需要添加間接另一個層次。記得; 應有盡有在C中按值傳遞。所以,你的函數應該採取row***作爲它的參數:

void get_rows(row ***rows) { 
    if(!rows) { 
     signal_some_error(); 
     return; 
    } 
    ... 
    *rows = malloc(rowNumber * sizeof(row*)); 
    ... 
} 

此外,作爲user1700513指出的那樣,你分配一個row*到行。這不能成爲你的實際代碼,因爲它會導致編譯器錯誤。

+0

該問題在get_rows返回之前顯示,直到賦值行後。它應該仍然工作,如果只在範圍內,對嗎? – cbaby

+0

所以,我上面提到的仍然是一個需要修正的錯誤,否則你的功能就沒用了。如果在函數內部存在問題,那麼你還沒有發佈所有相關的代碼。 'get_row'每次都會返回一個'malloc'd指針,所以除非你在內存的某個地方跺腳,否則你的問題會丟失一些東西。 'malloc'不可能在連續兩次返回相同的地址而沒有在兩者之間刪除。 'd.a'和'd.b'是否正確地終止了C字符串? 5'字節大到足以容納它們嗎?在將它傳遞給函數之前,你如何聲明'rows'? –

+0

@cbaby:...'rowNumber'的值是什麼?這裏缺少信息,我們需要更多的代碼。 –

3

變化row r = malloc(sizeof(row));row* r = malloc(sizeof(row));。我想知道爲什麼你沒有得到這個編譯器的警告。

+1

它應該是一個錯誤,因爲沒有從'void *'到'row'的隱式轉換。我敢打賭,這是一個錯字,真正的代碼聲明瞭一個指針。 –

+0

是的,錯字,對不起... – cbaby

+0

@cbaby:最好只是複製代碼逐字。你有沒有嘗試我的建議? –