使用int指针对malloc和free进行简单测试会导致双重释放或损坏错误

时间:2013-05-04 19:25:34

标签: c testing malloc free

要了解有关指针的更多信息,我只编写了一个简单的测试函数,该函数创建了一个指针,在shell上的某些输出之后分配空格和空格。

void main() {
  int *p = (int*) malloc(sizeof(int));
  int a = 42;
  printf("p: %x\n", p);
  printf("*p: %d\n", *p);
  printf("a: %s\n", a);
  printf("&a: %x\n", &a);
  p = &a;
  printf("p: %x\n", p);
  printf("*p: %x\n", *p);

  //Until now everything works as expected
  free(p); //ERROR
  // printf("p: %x\n", p); // Shall cause error, because space was freed
  // printf("*p: %x\n", *p); // Shall cause error, because space was freed
}

首先运行一切都很好。 free(p)没有造成任何错误。然后我尝试使用结构进行相同的测试并获得双重自由错误。 “好吧,也许我做错了什么,让我们开始吧”,我想,按Ctrl + Z将所有内容都放到上面,就像之前一样。现在我仍然得到这个错误。为什么?这是一个新手问题,我知道。上面的代码可以在网络上的任何地方找到,作为malloc和free的简单演示。就像这里:http://www.cplusplus.com/reference/cstdlib/free/ 希望,有人可以告诉我我做错了什么。

2 个答案:

答案 0 :(得分:3)

传递给free() 的指针必须从之前的malloc()(或calloc()realloc())调用返回。情况并非如此,因为p的地址为a之后:

p = &a;

然后将p传递给free(),导致未定义的行为。

请注意,在问题中链接的页面示例中,无论是在调用任何动态分配函数之后指针都被重新分配。


以下代码段中的评论"Shall cause error, because space was freed"不正确:

free(p); //ERROR
// printf("p: %x\n", p); // Shall cause error, because space was freed

因为打印指针的地址是安全的,无论它与之关联的内存是否为free()。如果您尝试访问free() d的内存,则 错误,因此此评论是正确的:

// printf("*p: %x\n", *p); // Shall cause error, because space was freed

因为p被引用并且正在尝试读取free()内存。


这是一个错误:

printf("a: %s\n", a); /* Must be '%d' as 'a' is an 'int'. */

请注意:

printf("p: %x\n", p);

也是未定义的行为:对指针使用%p格式说明符。见Correct format specifier to print pointer (address)?


Do I cast the result of malloc?

答案 1 :(得分:0)

void main() {
  int *p = (int*) malloc(sizeof(int));   // here is error number one.
                                         // you casted your fresh malloc'd int
                                         // to an int*
                                         // which is not what you want to do
                                         // get rid of the cast you don't need it.

   // here is where your problem continues.
  int a = 42;   // this variable A was created on the stack not the heap!!
                //you cant free this, which is what you are doing below.
  printf("p: %x\n", p);
  printf("*p: %d\n", *p);
  printf("a: %s\n", a);
  printf("&a: %x\n", &a);

  p = &a; // this is a correct statement. 
          // you getting the address of var a
          // and making pointer p point to A's contents.
  printf("p: %x\n", p);
  printf("*p: %x\n", *p);

  //Until now everything works as expected
  free(p); //ERROR: here you are trying to free var A 
           // but you cant because it wasnt dynamically allocated.
  // printf("p: %x\n", p); // Shall cause error, because space was freed
  // printf("*p: %x\n", *p); // Shall cause error, because space was freed
}
希望这会有所帮助。 我强烈建议您阅读K& R(Kernegie和Richie)C编程语言手册中的指针CH 5。 它真的很短,你可以在某处找到它免费在线。事实上,我推荐你阅读整本书。最好的c预订那里。 记住你只能释放你的malloced(记住每个malloc给你的堆内存块)