嵌入式 关于malloc(0)的问题

原创 2013年12月02日 14:51:53

最近,看了有关malloc(0)的返回值以及其他一些问题的讨论,我把自己的感受和看法记录如下:

问题:char* ptr = malloc(0*sizeof(char));

if(NULL == ptr)

      printf("got a NULL pointer");

else

     printf("got a Valid pointer");

请问:上面的程序输出为什么?在C99的标准里面解释到,如果给malloc传递0参数,其返回值是依赖于编译器的实现,但是不管返回何值,该指针指向的对象是不可以访问的。在VC6编译环境下,输出“got a Valid pointer”

但是我试图给该指针赋值,如:*ptr = ''a'' ;编译器并没有给出任何错误和警告信息,接着,我再输出该值,printf("*ptr=%d/n",*ptr) ;也可以正常输出。

但是当我用free(ptr) ;释放内存的时候,出现错误,为什么呢?下面是我看了网友经过讨论以后我比较认同的看法:

当malloc分配内存时它除了分配我们指定SIZE的内存块,还会分配额外的内存来存储我们的内存块信息,用于维护该内存块。因此,malloc(0)返回一个合法的指针并指向存储内存块信息的额外内存,我们当然可以在该内存上进行读写操作,但是这样做了会破坏该内存块的维护信息,因此当我们调用free(ptr)时就会出现错误。完整程序如下:

#include 
#include

int main()
{
 char *ptr ;
 ptr = malloc(0*sizeof(char)) ;
 
 if (NULL == ptr)
  printf("got a NULL pointer/n");
 else 
 {
  printf("got a Valid pointer/n");

  *ptr = ''a'
  printf("the value at %X is:%c/n",ptr,*ptr);

  free(ptr) ;//if we did not add this statement ,the program can run normnlly,or we will get 

// a runtime error.
 }
 return 0 ;
}

既然malloc另外分配内存来维护该内存块,也就是说分配来用于维护该内存块的内存的大小也是有限的,那么到底是多少呢?这和可能也依赖于实现,在VC6下,是56BYTE,下面是测试程序:

#include 
#include 
#include

int main()
{
 char *ptr ;
 ptr = malloc(0*sizeof(char)) ;
 
 if (NULL == ptr)
  printf("got a NULL pointer/n");
 else 
 {
  printf("got a Valid pointer/n");
  // 有56个a,另外有一个字节用于保存''/0'
  strcpy(ptr,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 
  //printf("the value at %X is:%c/n",ptr,*ptr);
  printf("the string at %x is :%s/n",ptr, ptr);
 // free(ptr);
 }
 return 0 ;
}

此时我们没有把free(ptr)编译进来,同样会发生异常,程序输出很多个56个a,我暂时还不明白为什么?????如果把free(ptr);编译进来,就会发生运行错误!

通过上面的讨论和程序的验证,确实证明了网友和我的想法是正确的,也就是malloc(0)还会额外分配一部分空间(在VC6下是56字节)用于维护内存块。

 

关于这个问题的个人理解:

1、ptr = malloc(0*sizeof(char)) ;
ptr是局部指针变量,存储在栈中,它的值是动态分配的一块堆中的空间的首地址
所以说这个地址是合法的,但是由于malloc的大小是0,故这个这个地址指向的堆中的存储空间的大小是0,
这个指针类似于一个野指针,可以使用的,但是是有风险的,因为不知道这个指针后面的内存空间被谁使用着,要是被核心进程使用,哪肯定会造成相应程序的崩溃
2.关于56个a的问题,我在本地测试是不存在的,我测试的是很多个都能打印出(用gcc测试)~
3.关于加上free后,程序会崩溃,我理解是由于在堆中并没有对应的空间分配到导致的~


实现一个简单的malloc

原文: http://www.ibm.com/developerworks/cn/linux/l-memory/ 参考: http://www.geeksforgeeks.org/memory-...
  • chj90220
  • chj90220
  • 2016年12月01日 15:41
  • 303

malloc、free与内存碎片

测试1 int *p=(int *)0x12ff7c; *p=NULL; p=NULL; 为什么在执行完第2条代码之后,发现p的值变为0x00000000(这有点匪夷所思吧?) int ...
  • parasoft
  • parasoft
  • 2014年04月30日 10:39
  • 958

C语言malloc的使用浅谈

C语言malloc的使用浅谈 参考文献:C_Free API文档 在c语言的编程中常常要对内存操作,而这对不少人来说是个不简单的问题。 最近在做作业的过程中常常看到在用到存储结构的地...
  • Zheng_Ky
  • Zheng_Ky
  • 2016年05月04日 15:32
  • 1588

关于STM32能否使用malloc申请动态内存的问题

首先,malloc( )属于标准C语言函数,当然可以在单片机上使用,如STM32可以先在启动文件中设置heap的大小,再使用动态内存分配:        Heap_Size     EQU    0x...
  • c12345423
  • c12345423
  • 2016年11月02日 09:10
  • 5190

c语言内存管理、野指针、malloc

C语言一共定义四个区块:代码区、全局变量和静态变量区、栈、堆 针对四个区块,用户的内存分配也有三种不同的方式: 静态变量区:在代码编译的时候就分配好了,比如全局变量,被static定义的变...
  • egbert123
  • egbert123
  • 2017年03月19日 09:40
  • 546

Malloc内存泄露和内存越界问题的研究

Malloc内存泄露和内存越界问题的研究 2013-03-02 22:59:32 分类: LINUX 原文地址:Malloc内存泄露和内存越界问题的研究 作者:gongcb Ma...
  • u011761947
  • u011761947
  • 2013年10月22日 11:11
  • 1147

malloc()和free()函数的讲解以及相关内存泄漏问题

1、函数原型及说明: void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。 ...
  • doniexun
  • doniexun
  • 2014年07月30日 10:53
  • 1696

嵌入式经典面试题-嵌入式程序员必须知道的0x10个基础问题

C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相...
  • Years_pass
  • Years_pass
  • 2016年12月21日 15:55
  • 849

嵌入式软件工程师经典笔试题

> 预处理器(Preprocessor)  1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)  #define SECONDS_PER_YEAR (60 * ...
  • xiaoshengyige
  • xiaoshengyige
  • 2013年09月22日 14:17
  • 37100

malloc内存分配与free内存释放

这里的存储分配程序,讲的就是标准库中malloc函数的实现原理。首先要了解针对malloc的内存存储结构。malloc不像全局变量一样,不是在编译器编译的时候就会分配内存空间,而是在调用到malloc...
  • diaozaoxiang
  • diaozaoxiang
  • 2016年09月04日 16:56
  • 2146
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式 关于malloc(0)的问题
举报原因:
原因补充:

(最多只允许输入30个字)