2010-08-18 174 views
1

我有functon是轉換列表數組:轉換列表陣列

void* list_to_array(SList* list) 
{ 
    int i; 
    int array_size = list_get_length(list); 

    void* array[array_size]; 

    for (i = 0; i < array_size; i++) 
    { 
     array[i] = list_get_n_data(list,i); 
    } 

    return *array; 
} 

但是當我嘗試測試它:

int* a = (int*)list_to_array(list); 
printf("%d" (int)a); 

它的確定。我看到第一個元素。但是,當我試圖讓第二個或第三個元素:

int* a = (int*)list_to_array(list); 
a++; 
printf("%d" (int)a); 

我看到的第一個元素+ 4,如果我嘗試獲得第三個元素我看到第一個元素值+ 8等..爲什麼呢?怎麼了?

謝謝

+1

你只返回數組的第一個元素。不知道剩下的東西,什麼都不能說(除非你不應該想到返回指向局部變量的指針)。 – 2010-08-18 15:23:17

回答

6

您正在返回一個指向堆棧內存位置的指針。一旦函數返回,該內存區域就不再有效。

另外,不是實際返回指向數組的指針,而是返回數組中的第一個元素。下面的代碼將返回1,而不是數組的指針。

int array[] {1, 2, 3, 4}; 
return *array 

您可能只需對代碼進行微小的更改即可使其工作。

void** array = (void **) malloc(sizeof(void *) * array_size); 
... 
return array; 

只要確保您釋放內存使用的內存時array完成它。

void **array = list_to_array(list); 
// Use array 
... 
// Finished with array 
free(array); 
+1

他寫道:**返回*數組; ** 也許那是有效的東西?我們不會從他的代碼中知道。 – 2010-08-18 15:23:58

+0

謝謝你的回覆。我怎樣才能返回數組? – 0xAX 2010-08-18 15:29:17

+0

+1使用malloc()分配內存空間將確保您的數組即使在函數返回後仍然存在。 – karlphillip 2010-08-18 15:56:40

1

當您增加指針int* a 1,它實際上由sizeof(int)增加它,這是 - 在大多數系統上,至少 - 4

所以,如果

int* a = 0x40b8c438 

然後

a + 1 
     = ((void*) a) + sizeof(int) 
     = 0x40b8c43c 

a + 2 
     = ((void*) a) + sizeof(int) * 2 
     = 0x40b8c440 
0

您在這裏有三個問題。第一個很簡單,你返回的數組的第一個元素爲return *array,當你的意思是返回一個指針到數組的第一個元素return array。不要停止在這裏!第二個是你將指針遞增1,而不是你指向的數據的大小。這會導致你得到錯誤的結果。第三個問題要嚴重得多:
你爲你的陣列上這一行分配內存:

void* array[array_size]; 

該內存分配在棧上,當你從函數返回該內存不再分配。當您稍後使用該行引用此內存時:

int* a = (int*)list_to_array(list); 

a指向堆棧上不再使用的區域。用你的代碼得到一些合理的結果,但是如果你從函數返回後修改了堆棧,a將會指向新的內存。例如,如果使用以下代碼:

int* a = (int*)list_to_array(list1); 
int* b = (int*)list_to_array(list2); 
printf("%d" (int)a); 

您將(可能)看到b的第一個元素。這不能保證 - 您也可能會遇到分段錯誤。分配給a及其使用的其他代碼也會覆蓋您在printf語句中訪問的內存內容。

您需要分配與a相同範圍的內存。

// Prototype 
void* list_to_array(SList* list, void* dest_array); 

// C99 (Or use malloc) 
void* array[list_get_length(list)];     

int* a = (int*)list_to_array(list, array); 
other_functions();  
// Works every time! 
printf("%d" (int)a);  

不太嚴重的問題是,您沒有按照正確的數量遞增指針。您需要使用sizeof()運算符。或者,您可以使用[]訪問數組元素。

int* a = (int*)list_to_array(list, array); 
printf("%d" a[1]); //Prints second element of a 
a += sizeof(int) * 2; 
printf("%d" (int)a); //Prints third element of a 
0

你需要小心使用指針,聲明它是這樣的:

int main() 
{ 
    int *array; 
    int i; 
    i = size(list); 
    array = list_to_array(list, i); 

... 
free(array); 
} 

int  size(t_list *list) 
{ 
    int i; 

    i = 0; 
    while (list) 
    { 
     i++; 
     list = list->next; 
    } 
    return (i); 
} 

int  *list_to_array(t_list *list, int size) 
{ 
    int  *array; 
    int  i; 
    t_list *temp; 

    i = 0; 
    if (list == NULL) 
     return (NULL); 
    array = (int*)malloc(sizeof(int) * size + 1); 
    temp = list; 
    while (temp) 
    { 
     array[i] = temp->data; 
     temp = temp->next; 
     i++; 
    } 
    return (array); 
}