2014-01-11 53 views
3

我的問題是關於'realloc'。 下面的代碼工作正常(無警告):重新分配到一個函數

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int num=10; 
    int *vet; 
    int i; 

     for (i=0; i<num; i++) 
    { 
     /* allocate memory of vet to contains (i+1) int */ 
     vet = (int*) realloc (vet, (i+1) * sizeof(int)); 

     /* write numbers in the allocated memory */ 
     vet[i] = 321 + i; 
    } 

    /* print test, if all works I must see: 
    | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | */ 
    printf ("| "); 
    for (i=0; i<num; i++) 
     printf ("%d | ", vet[i]); 
    printf ("\n"); 

    return 0; 
} 

但隨着功能相同的程序不能正常工作!而編譯器返回以下警告:

In function ‘main’: 
14:10: warning: ‘vet’ is used uninitialized in this function [-Wuninitialized] 

的代碼是:

#include <stdio.h> 
#include <stdlib.h> 

void memoria (int *, int); 

int main() 
{ 
    int *vet, num=10; 

    memoria (vet, num); 

    /* print test, if all works I must see: 
    | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | */ 
    int i; 
    printf ("| "); 
    for (i=0; i<num; i++) 
     printf ("%d | ", vet[i]); 
    printf ("\n"); 

    return 0; 
} 

void memoria (int *vet, int num) 
{ 
    int i; 

    for (i=0; i<num; i++) 
    { 
     /* allocate memory of vet to contains (i+1) int */ 
     vet = (int*) realloc (vet, (i+1) * sizeof(int)); 

     /* write numbers in the allocated memory */ 
     vet[i] = 321 + i; 
    } 
} 

有人能說我爲什麼?非常感謝你!

哦,並與主體工程(與功能)的 '隨機' 的malloc相同的代碼...

#include <stdio.h> 
#include <stdlib.h> 

void memoria (int *, int); 

int main() 
{ 
    int *vet, num=10; 

    /* ADDED MALLOC */ 
    vet = (int*) malloc (1); 

    memoria (vet, num); 

    /* print test, if all works I must see: 
    | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | */ 
    int i; 
    printf ("| "); 
    for (i=0; i<num; i++) 
     printf ("%d | ", vet[i]); 
    printf ("\n"); 

    return 0; 
} 

void memoria (int *vet, int num) 
{ 
    int i; 

    for (i=0; i<num; i++) 
    { 
     /* allocate memory of vet to contains (i+1) int */ 
     vet = (int*) realloc (vet, (i+1) * sizeof(int)); 

     /* write numbers in the allocated memory */ 
     vet[i] = 321 + i; 
    } 
} 
+1

改變你的函數接受int ** vet然後調用memoria(&vet,num); '從主。也不要施加malloc或realloc的結果,因爲它可以使有價值的診斷消失,也看起來很糟糕。 – Brandin

+0

但是矢量名稱已經是它的第一個元素的指針了!對? –

+3

_以下代碼正常工作(沒有警告):_第一個代碼''vet'也被使用了未初始化的。 – BLUEPIXY

回答

6

你有這樣的表述方式:

int *vet, num=10; 

memoria (vet, num); 

的變化你在memoria裏面不會被送回main。爲了理解這一點,僅僅爲了好玩,改變num而不是memoria的值,然後在main中檢查它。主值仍然是10。變量vetnum按值傳遞,以便它們保留其原始值main

這兩種最常見的方法是通過vet的地址,以便memoria可以修改它,或者返回vet的新值。

第一種形式是這樣的:

memoria(& vet, num) ; 

void memoria (int **vet, int num) 
{ 
    * vet= realloc(* vet, ...) ; 

或者,而是可以改變的memoria返回類型,

vet= memoria(vet, num) ; 

int * memoria(int * vet, int num) 
{ 
    ... 
    return vet ; 
} 

他們都有自己的優點和缺點。對於不是指針頭的人來說,第二種形式可能更容易遵循。

的malloc/realloc的僥倖

您的最後一個例子成功運作的原因是很容易看到,如果你在printf s添加到mainmemoria顯示的vet值。如果可以,realloc()將新內存放在與舊指針相同的位置。在你簡單的測試用例中,分配器很容易做到,所以內存保持在同一個位置。如果代碼更復雜,並且撥打realloc()的指針移動指針,則在之後您會看到main的崩潰。

+1

謝謝你的回答! 'num'是按值傳遞的,沒關係,因爲我不想改變它,但是'vet'?用'memoria(vet,num);'給函數傳遞一個指針,對吧? –

+1

@user。是的,你傳遞一個指針,但你的函數*改變了它自己內部的指針('vet = realloc(vet,...)',但是不會將修改過的指針返回到'main()' – Roddy

+2

謝謝,現在我明白了!但是如何解決這個問題?(以及爲什麼我發佈的最後一個代碼工作正常?) –

1

您正在傳遞一個未初始化的vet *來重新分配。 Realloc()就像free()以防萬一它分配全新的內存(它是free()是舊分配)。所以傳遞給realloc()的指針最好是有效的堆指針或空指針。

2

照顧這幾個問題,你很好走。

您的main不回收vet其實際指向的東西。以某種方式將vet返回到您的main vet

int *vet = NULL; //better bet for realloc() in this case 
vet= memoria (vet, num); 

相應地更改原型返回一個指針,並記得在定義中返回vet

int* memoria(int*, int); 

現在到realloc()。 Accoring到ISO C

若ptr爲null pointerrealloc()應當相當於malloc() 爲指定大小。

若ptr不匹配的指針早些時候返回,由calloc(), malloc()realloc()或者如果空間之前已經釋放 通過調用free()realloc(),該行爲是不確定的。

希望有所幫助。

+1

非常感謝! ,例如,對於一個結構'struct example * e;'是同樣的權利?你現在爲什麼我發佈的最後一個代碼有效?謝謝! –

+0

另一個問題:如果我想用void函數解決問題? –

+1

是的,在你最後的片段中,* vet *只是一個指向你所擁有的內存塊的指針cated。您已將此指針傳遞給重新分配它的函數。realloc()返回一個新的指針值,其值* may *或*可能不會與舊的指針值相同。並且您的舊內容以某種方式保存下來! – Gil