C中的重新分配空间函数.

Andy84920 2003-09-29 06:45:51
#define SIZE 100
int array* = (int *) malloc (SIZE * sizeof(int));
//向array数组赋SIZE个值.
........
现在要扩展数组大小.想搞成两倍的SIZE.
用: array * = (int *)relloc( array*, SIZE*2*sizeof(int));
//不太记得这个函数原形了.好像是这样的吧?

我的问题是:
relloc是先申请两倍SIZE大小的空间,然后让array指向这个空间,再把原来array指向空间的数据"复制"到这个重新分配的空间中来,最后释放掉那个最开始malloc来的空间的吗?因为不可能在原来的地址的最后再申请空间是吧.要全部重新分配才可以呀.那值是如何搞过来的呢?
如果是这样,我觉得这个效率不是很低吗?毕竟复制这么多数据要的时间很多.
...全文
224 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
WYC2300 2003-10-08
  • 打赏
  • 举报
回复
哪位大峡能够有更深的体会那四个的用处

来个邮件哦

wyc236657_cn.student@sina.com
hubs 2003-10-08
  • 打赏
  • 举报
回复
天光早的说的且不论是对是错,但觉得他能从其他方面来考虑,就是一篇好文章,你们认为呢???
rogear 2003-10-08
  • 打赏
  • 举报
回复
没用过realloc(),我连malloc都用得很少,一般只是模块初始化的时候一次性用malloc申请好,避免中间不停的调用malloc
Andy84920 2003-10-07
  • 打赏
  • 举报
回复
几天没时间上网.今天逛了一晚CSDN.

翻开这个帖子让我想起了以前看到有人说C++的new delete和C的malloc free
的关系.它们如何比?比什么?有没有可比性?为什么?

希望真正能说的来说几句!我想这才是我们想看到的帖子,而不是什么UP,MARK之类的!
FishCrazy 2003-10-02
  • 打赏
  • 举报
回复
短歌说得对,两种情况都是可能的

我做过测试,realloc以后,得到的地址绝大多数是和之前一样的
TianGuangZao 2003-10-02
  • 打赏
  • 举报
回复
呵呵,主题写着讨论的是 C。
不过我也很想听听 C++ 中 new 和 delete 的具体细节。
plusir 2003-10-02
  • 打赏
  • 举报
回复
佩服楼主,好久没看到这样的帖子了,最近总是看些让人代写作业或者一编译不过就帖大段代码让人调试的帖子,无聊。楼主的问题我不会,学到了不少东西,惭愧的是从来没有想过深入的了解一下。不过我觉得动态内存分配用new和delete会不会更好,那位牛人说一下
短歌如风 2003-10-02
  • 打赏
  • 举报
回复

new和delete是为了C++对象类型的动态分配引入的,它们的特点在于自动调用构造函数和析构函数,并且new在内存分配失败时会抛出异常,因此不用对返回值进行检查。

  由于它们考虑到对象类型,并且考虑到对象的状态有可能依赖this指针,所以没有提供相应的realloc版本(认为用memcpy复制对象数组是个错误),所以在使用PODS类型并且需要realloc能力时还是不要使用new和delete了。(我认为C++的这个考虑并不太好,应该提供realloc的new操作,由程序员决定是否使用,这才符合C++“选择的自由”的精神。)而STL中的vector著名的resize低效也正是的原因,所以我在使用PODS时总是选择basic_string作为顺序存储容器。
TianGuangZao 2003-10-02
  • 打赏
  • 举报
回复
To Andy84920(你也不懂):
可以去看看有关动态内存管理的书:
如《数据结构》严薇敏
或《OPERATION SYSTEM CONCEPTS 》第六版,中文名《操作系统概念》影印,很有名气的恐龙书。
里面都专门有一章的篇幅讲操作系统的动态内存管理。
我们在编译时经常讲的堆其实是内存中我们动态分配内存的地方,刚开始是完整的一整块空闲的内存,经常使用后被分割成很多块,有的块是被使用,称为占用块,有的块未被使用,称为占用块,它们交叉出现,使整个内存区呈现这些占有块和空闲块犬牙交错状态。
每个块里头都包含了一个记录结构,记录了该块的使用情况,或称之为内存状态。
我们可以把这些空闲块用链表的形式串联起来,按需分配内存和回收释放了的内存。
当然这只是最简单的方式,还可以采取比较复杂的如常见的 virtual pages。

明白这个原理后,你上面提到的问题就不难理解了。
当使用 realloc 时,先检查相邻的块是否空闲而且足够满足要求。如果有足够空间,那么直接重新分配即可,不必移动到新的空闲块。
当然通过 virtual pages 技术可以做到让数据的不同部分分布在物理空间不相邻的 frames 上,这可能也就是为什么绝大多数情况地址都和以前一样的原因吧。
当然这主要依赖操作系统,是 malloc 的实现者所要关心的事,不必我们劳神的。

实际的 malloc 实现当然要复杂的多,如果对这方面有兴趣,可以看下面我推荐的文章:
Memory Management talk by Rik van Riel

http://www.kernelnewbies.org/documents/irclogs/mm.log
Too little, too slow
An introduction to memory management and Linux memory management today and tomorrow
http://www.surriel.com/lectures/mmtour.html
两篇连起来看。
这个是 linux 下 malloc 的实现者写的。

如果你觉得效率上的问题,至少你得先看懂别人写的代码,才能下结论是好是坏。
Andy84920 2003-10-01
  • 打赏
  • 举报
回复
还有没有人有高见??>?
Andy84920 2003-09-30
  • 打赏
  • 举报
回复
TO: plainsong(短歌)

"如果你在调用前只把这段内存的地址保存在array中,上面的调用会在realloc失败时导致你无法再找到这段内存地址,也就无法释放它。"

realloc失败时它返回NULL,但为什么会导致无法再找到这段内存地址呢?
它应该是重新分配成功才会让array改变指向的,如果没有重分配成功它还是指向原来的内存区.这样才是它内部要处理好的.为什么在失败时让它无法找到这段内存并释放 呢?搞不懂.
Andy84920 2003-09-30
  • 打赏
  • 举报
回复
TO: playboyxp(learning)

可能是

"将p所指向的已经分配内存的大小改为size,size可以比原来分配的空间大或小"这样吗?

我认为这里的P是用来为了复制数据才有用的.在它后面再加内存,这不太可能,因为这里的内存可能已被占用,要重新分配内存必需全部重新分配.

楼上的和我好像一个意思.

那前面几位同志的意思是,如果不移动它就直接在其后面加找内存.而如果移动的话它就会复制数据然后释放掉原来那块地方的内存咯???

这里还是要谈到复制的问题.效率的问题.
cxjddd 2003-09-29
  • 打赏
  • 举报
回复
不记得原型了?打开头文件看看就得了。

我觉得 realloc () 分配的不可能和原来 malloc () 是一个地址。

用 realloc () 一定会有复制的过程。
playboyxp 2003-09-29
  • 打赏
  • 举报
回复
用realloc()函数
原型void *realloc(void *p,unsigned size)
将p所指向的已经分配内存的大小改为size,size可以比原来分配的空间大或小
短歌如风 2003-09-29
  • 打赏
  • 举报
回复
realloc“可能”会发生内存移动,这时返回值就是新的地址,也可能不移动,这时返回值和传入值相等。关键就是如果不移动的话能不能完成“重分配”。

array = (int *)realloc(array, NewSize)这种写法很危险,因为realloc除了“移动内存”、“不移动内存”外还有一种情况就是“重分配失败”,这时它返回NULL,而原来的内存并不会被释放。如果你在调用前只把这段内存的地址保存在array中,上面的调用会在realloc失败时导致你无法再找到这段内存地址,也就无法释放它。一般下面的调用方法已经成了常识:
{//放到复合语句中以便定义变量
int * Temp = (int *) realloc(array, NewSize);
if (Temp == NULL)
{
//错误处理
}
else
array = Temp;
}
TianGuangZao 2003-09-29
  • 打赏
  • 举报
回复
写错了。

正确应该是:
int * array = (int *)malloc(SIZE * sizeof(int))

int * array = malloc(SIZE * sizeof *array)

下一条感觉更好。

我记忆中 relloc 好像不是你说的那样分配的。
如果原来的地方还有足够的空闲空间可供分配,那么就不用再另外找其它空闲空间。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧