2010-02-04 122 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()调用的逻辑上。我纠正了它,目前该程序运行良好。我的函数现在返回指向已分配内存块的指针。