| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2968 人关注过本帖
标题:关于malloc和realloc的疑惑
只看楼主 加入收藏
刮目相看
Rank: 2
等 级:论坛游民
帖 子:25
专家分:30
注 册:2009-11-23
结帖率:50%
收藏
 问题点数:0 回复次数:8 
关于malloc和realloc的疑惑
假如定义静态数组:int arr[3]={1,2,3};
因为是以整形数组形式定义,所以当打印*(a+0)...等值时,系统知道每次要一定移动sizeof(int)个字节数,切每个值的地址是相邻的。

但是如果这样定义:
int *a=(int *a)malloc(sizeof(int));
*a=1;
a=(int *)realloc(a,2*sizeof(int));
*(a+1)=2;
a=(int *)realloc(a,3*sizeof(int));
*(a+2)=3;

之后如果想要打印*a,*(a+1),*(a+2)也可以打印出来。
但是,又malloc类函数分配的内存不是不一定连续么?

为什么还可以用数组的形式去取之中的值呢?就是*a,*(a+1),*(a+2),这样表示,不是说明这三值的地址是连续的么?

疑惑中
搜索更多相关主题的帖子: malloc realloc 
2010-03-11 06:18
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:0 
谁说不是连续的?????



人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-03-11 08:59
ldg628
Rank: 12Rank: 12Rank: 12
等 级:火箭侠
威 望:3
帖 子:526
专家分:3036
注 册:2009-6-23
收藏
得分:0 
malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用 户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给 用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片 段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检 查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。--百科上的一段
realloc原理差不多,只不过它是放大缩小空间,在原址上申请不到足够大的空间时,再找另外一块,所以此时的原地址会不一样,如果实在找不到那么大的了,就返回NULL。
程序在访问内存时,应该有特殊处理,内存块有个表头,记录当前该块的各种信息,像如果我们从中间释放一段我们申请的空间,就会出错,应该是读错了表头,产生了不可预想的结果。这些对用户是不可见的,我们只要把它们当成是连续的就行了
我前段时间看过一下这方面的代码,好像是这样的,如有错误,有劳大侠们帮指正了

2010-03-11 10:35
cnfarer
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:179
帖 子:3330
专家分:21157
注 册:2010-1-19
收藏
得分:0 
这类函数是在堆上分配内存的。
realloc:扩大内存,如果原先的内存大小后面有足够的空间,自然得到一块连续的空间,什么问题也没有。如果没有足够的空闲空间用来分配,那么且从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中,返回新的mem_address指针。(数据被移动了),老块被放回堆上(在这种情况下,稍不注意就可能产生不可想象的后果)。否则返回null。

★★★★★为人民服务★★★★★
2010-03-11 10:49
刮目相看
Rank: 2
等 级:论坛游民
帖 子:25
专家分:30
注 册:2009-11-23
收藏
得分:0 
楼上2位朋友说的这些我懂。
但是如果是连续的内存空间,那为什么还要用链表?用指向下一个node的指针去找到下一个,如果确定是连续了,那不就直接用数组的形式去遍历每一个元素了?
2010-03-11 14:10
mywaylgh
Rank: 8Rank: 8
来 自:厨房
等 级:蝙蝠侠
威 望:5
帖 子:188
专家分:729
注 册:2010-3-10
收藏
得分:0 

确实如楼上所说
数组的效率是链表无法比拟的

从我写过的C看,没碰到一定要用链表才能解决的问题

正在想链表是不是C的多余的东西???

还是我写的程序太少?

同样期待高手

人生就像茶几 上面放着许多杯具

人生也像厨房 里面总有一些洗具
2010-03-11 14:18
cnfarer
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:179
帖 子:3330
专家分:21157
注 册:2010-1-19
收藏
得分:0 
如果是一个有序序列,要插入一个元素,你说用数组好,还是链表好!而且很明显,上面已经说过了,使用realloc时可能出现的情况及意外!如果用链表,可能只需要增加一个节点!

★★★★★为人民服务★★★★★
2010-03-11 15:05
cnfarer
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:179
帖 子:3330
专家分:21157
注 册:2010-1-19
收藏
得分:0 
如果仅从实现来说的话,手工制造的汽车,有几个人买得起啊?

★★★★★为人民服务★★★★★
2010-03-11 15:08
zhddragon
Rank: 5Rank: 5
等 级:职业侠客
帖 子:208
专家分:346
注 册:2009-5-14
收藏
得分:0 
回复 5楼 刮目相看
malloc 类函数只能保证同一次调用申请返回的内存块逻辑地址连续。

这类函数通常会出现在元素个数在编码时不能确定而要到运行时才能确定的时候,在这种情况他们相对于数组的优势是节省内存空间(C89),保证程序的健壮性,缺点是耗费额外的函数调用时间。例如有一个程序要求将某一个班的所有的人的名字读入内存(这里班级的人数可以是不定的,可以是很少也可以很多),如果你用数组,那么你就要预计的一个最大值MAX,但一般情况下一个班都会少于这个MAX,那么你的程序就会占用了不必要的内存空间,而且更大的问题是如果突然出现一个比这个MAX还大的班级,那么这个程序可能直接崩掉,但用malloc就可以解决上面的问题。


链表的使用很多时候是为了消除大的数据块的移动,提高程序的效率。

身体是玩命的本钱
2010-03-12 00:41
快速回复:关于malloc和realloc的疑惑
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016838 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved