2010-02-04 158 views
1

有誰能告訴我爲什麼這個程序給出了一條調試錯誤消息
「損壞:在0x00430050正常塊(#42)之後」。 消息在線路空閒(ptr)上生成;
我想這個問題與內存的重新分配有關。動態內存重新分配問題

#include<stdio.h> 
#include<stdlib.h> 
#define DELTA 5 

void include(int d,int* p,int n,int k,int flag); 

void main(void) 
{ 
int *ptr;  
int i=0,digit,koef=1; 

ptr=(int *)malloc(DELTA*sizeof(int)); 
fp=fopen("test.txt", "r")) 
do{  

     fscanf(fp,"%d",&digit); 
     if (!(i % DELTA)) 
     koef++; 
     if(i<(DELTA*koef)) 
     include(digit,ptr,i,koef,1); 
     else 
     include(digit,ptr,i,koef,2); 
     i++;  
    } 

}while(!feof(fp));  

free(ptr);  
} 

void include(int d,int* p,int n,int k,int flag) 
{ 
    switch(flag){ 
     case 1: *(p+n)=d;break; 
     case 2: if((p=(int *)realloc(p,k*DELTA*sizeof(int)))==NULL){ 
       printf("Error!Memory not allocated!\n"); 
       exit(1); 
} 
     *(p+n)=d;break; 
} 
} 
+1

您應該將代碼縮減爲產生錯誤的小版本。因爲它很複雜。 – 2010-02-04 14:33:48

+0

Realloc不應該導致這樣的問題,但我也使用它時遇到了麻煩。一般來說,我更喜歡做這樣的事情: int * tmp = malloc(new_size); memcpy(tmp,ptr,old_size); free(ptr); ptr = tmp; 不知道,如果它在這裏有用,儘管... – mingos 2010-02-04 14:39:36

回答

6

你正在傳遞ptr到你的函數,然後使用realloc來改變它。您需要將指針傳遞給指針才能正常工作。

我建議你在調用realloc之前和之後打印出指針指向包含的調用之前和之後的地址。這應該告訴你發生了什麼或者看一下下面的代碼:

#include <stdio.h> 

void a(int **ptrptr) 
{ 
    printf("ptrptr = %p, ptr = %p\n",ptrptr,*ptrptr) ; 
    *ptrptr = (int*)realloc(*ptrptr, 10*sizeof(int)) ; 
    printf("ptrptr = %p, ptr = %p\n",ptrptr,*ptrptr) ; 
} 


int main(int argc, char **argv) 
{ 
    int *ptr = malloc(5*sizeof(int)) ; 
    printf("ptr = %p\n",ptr) ; 
    a(&ptr) ; 
    printf("ptr = %p\n",ptr) ; 
    free(ptr) ; 
    return 0; 
} 
1

realloc()呼叫include()可移動的塊。這就是爲什麼realloc()返回一個指針,告訴你它最終放置數據的位置。您的代碼暫時使用該值(您將其存儲在本地變量p中並使用它),但無法將其傳播回調用方。 main()函數在其局部變量ptr中保留一個指向原始塊的指針,並且它永遠不會改變。

請記住,當您將參數傳遞給某個函數時,該函數將獲得自己的副本。在這裏,您將ptr的內容作爲參數傳遞,include()將該值視爲名爲p的變量,但此p僅爲ptr的副本。 ptr看不到p的修改。

您可以修改include(),以便它返回新指針;是這樣的:

int *include(int d,int* p,int n,int k,int flag) 
{ 
    ... 
    return p; 
} 

,然後調用它:

ptr = include(digit, ptr, i, koef, 1); 

這是傳播回新指針值給調用者的方式。

旁註:

  • main()應返回int,不void
  • 您不必施放malloc()realloc()的返回值。這些函數返回一個void *,C編譯器可以在沒有顯式強制轉換的情況下將其快速轉換爲任何類型的指針。明確的轉換是告訴編譯器的一種方式:「閉嘴,我知道我在做什麼」。因爲在這種情況下,編譯器不會談論任何東西,所以這隻會浪費源代碼空間。此外,在編譯器已大聲警告的某些情況下,轉換可能有害:如果malloc()被拼寫錯誤,編譯器會假定它返回int,並會警告將int用作指針;但演員將阻止該警告。
  • 你的代碼不能編譯,還有一個額外的大括號。
0

非常感謝! 您的評論真的很有幫助。 問題出在函數include()調用的邏輯上。我糾正了它,目前該程序運行良好。我的函數現在返回指向已分配內存塊的指針。