动态内存分配问题

时间:2010-02-04 14:29:45

标签: c

任何人都可以告诉我为什么这个程序给出了一个带有消息的调试错误 “损坏:正常阻止后(#42)在0x00430050”。 消息是在线上自由生成的(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;
 }
}

3 个答案:

答案 0 :(得分:6)

您正在将ptr传递给您的函数,然后使用realloc更改它。您需要将指针传递给指针才能使其正常工作。

我建议你在调用include之前和之后以及调用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 :(得分:1)

realloc()中的include()电话可能会移动该区块。这就是realloc()返回指针的原因,告诉你最终放置数据的位置。您的代码暂时使用该值(将其存储在本地变量p中并使用它)但无法将其传播回调用方。 main()函数在其ptr局部变量中保留一个指向原始块的指针,它永远不会改变。

请记住,当您将参数传递给函数时,该函数会获得自己的副本。在这里,您将ptr的内容作为参数传递,include()将该值视为名为p的变量,但此p只是{{1}的副本}}。 ptr没有看到p的修改。

您可以修改ptr以便它返回新指针;类似的东西:

include()

然后用:

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

这是一种将新指针值传播回调用者的方法。

附注:

  • ptr = include(digit, ptr, i, koef, 1); 应该返回main(),而不是int
  • 您无需转换voidmalloc()的返回值。这些函数返回realloc(),C编译器很乐意将其转换为任何类型的指针而无需显式转换。显式转换是一种告诉编译器的方法:“闭嘴,我知道我在做什么”。因为在那种情况下编译器无论如何都不会说话,演员表只是浪费源代码空间。此外,在编译器 已大声警告的某些情况下,强制转换可能是有害的:如果void *被错误拼写,编译器会认为它返回malloc(),并且警告使用int作为指针;但演员会阻止这种警告。
  • 您的代码无法编译,还有一个额外的结束括号。

答案 2 :(得分:0)

非常感谢! 你的评论非常有帮助。 问题在于函数include()调用的逻辑。我纠正了它,目前程序工作正常。我的函数现在返回指向已分配内存块的指针。