内存分配——realloc()函数的使用

首先看一下下面的C程序片断:

 

#i nclude <malloc.h>

char  *p;

p = (char * ) malloc (10);

p = (char * ) realloc (p,20);

…………………………

 

    这段程序的意思很简单,只有稍有点C基础的人都可以看懂。函数首先定义了一个字符型的指针p,然后为指针p分配了一个10个字节大小的内存空间,接着将这个内存块的大小增加到20个字节。

 

    这里有什么问题吗?上机运行一下,好像没有问题!

 

    是的,这样上机运行是没有问题的,但是这里存在着也许我们不太注意的隐患!隐患在那里?这就是我在本文中要详细说明的realloc()函数了。

 

    再看一下下面一段来自MSDN的话:

realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

这段E文还不算是晦涩难懂,所以我就不翻译了,大致的意思是说关于realloc返回值的。但是这里对他的返回值分了几种情况:

1、  返回void * 指针,调用成功。

2、  返回NULL,当需要扩展的大小(第二个参数)为0并且第一个参数不为NULL,此时原内存变成了“freed(游离)”的了。

3、  返回NULL,当没有足够的空间可供扩展的时候,此时,原内存空间的大小维持不变。

 

第一种情况告诉了我们在得到需要的内存空间后需要做类型转换的工作;

第二种情况可能只有傻瓜才会去使用吧!

第三种情况,内存空间不够的时候就会维持未来的大小不变。

 

        MSDN上面说内存空间不够的时候就不会扩展原来的内存空间的大小,这话固然没有错,但是有点含糊,似乎遗漏了一种情况!我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;可如果数据后面的字节不够的话,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。这句话传递的一个重要的信息就是数据可能被移动!看到这里,也许我们已经发现一开始我给出的程序的问题了。为了更清楚地说明问题,可以将上面的程序改成下面的形式:

 

#i nclude <malloc.h>

char  *p,*q;

p = (char * ) malloc (10);

q=p;

p = (char * ) realloc (p,20);

…………………………

 

    这段程序也许在编译器中没有办法通过,因为编译器可能会为我们消除一些隐患!在这里我们只是增加了一个记录原来内存地址的指针q,然后记录了原来的内存地址p,如果不幸的话,数据发生了移动,那么所记录的原来的内存地址q所指向的内存空间实际上已经放回到堆上了!这样一来,我们应该终于意识到问题的所在和可怕了吧!

 

    这个问题似乎有点牛角尖的味道,因为我们也许从来不曾遇上过,但是我们应该明白这样的事情的始终存在,只有这样,在万一我们碰上的时候才会去有意识的去避免这种隐患,否则,一旦这样的隐患一旦发作,程序崩溃不说,恐怕查错也不是一件容易的事!

 

    候俊杰在《深入浅出MFC》中引用林语堂的《朱门》中的一句话,我很有感触,虽然不可能有他的感触深,但是抱着向前辈学习的心态,所以也拿来作为本为的结束:

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sshcx/archive/2006/11/14/1384039.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
realloc函数用于重新分配已分配内存块的大小。它的语法如下: ```c void *realloc(void *ptr, size_t size); ``` 其中,ptr是一个指向已分配内存块的指针,size是需要重新分配的内存块的新大小。该函数的返回值是指向新分配内存块的指针。 使用realloc函数时需要注意以下几点: 1. 如果ptr为NULL,则该函数等同于malloc(size),即重新分配一个新的内存块。 2. 如果size为0,则该函数等同于free(ptr),即释放已分配的内存块。 3. 如果realloc函数无法重新分配内存块,则它会返回NULL,原有的内存块不会被释放。 4. 如果新分配的内存块大小比原来的内存块大小小,则新分配的内存块中可能会出现未定义的行为,因此需要小心使用。 以下是一个示例代码: ```c #include <stdio.h> #include <stdlib.h> int main() { int *p = (int*)malloc(5 * sizeof(int)); if (p == NULL) { printf("Failed to allocate memory\n"); return 1; } for (int i = 0; i < 5; i++) { p[i] = i; } p = (int*)realloc(p, 10 * sizeof(int)); if (p == NULL) { printf("Failed to reallocate memory\n"); return 1; } for (int i = 5; i < 10; i++) { p[i] = i; } for (int i = 0; i < 10; i++) { printf("%d ", p[i]); } free(p); return 0; } ``` 该程序首先分配了一个包含5个int类型元素的内存块,然后使用realloc函数将其重新分配为一个包含10个int类型元素的内存块,并将新增的5个元素赋值为5到9。最后,程序释放了已分配的内存块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值