堆得生长方向问题

striveQiao 2018-10-04 11:29:16
老师说堆得生长方向和栈的生长方向相反是递增的,但我自己测出来确实和栈的生长方向一样是递增的。为什么啊?哪里错了啊?
 #include "stdio.h"
#include "string.h"
#include "stdlib.h"
char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=%d,p2=%d\n", p1, p2);
free(p1);
free(p2);
return 0;
}
void main(void)
{
char *q=NULL;
q = str();//堆的生长方向:p1到p2地址递减了
}
...全文
875 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
tfrist 2018-10-25
  • 打赏
  • 举报
回复
jianggehappy01 可以结贴了
AlbertS 2018-10-12
  • 打赏
  • 举报
回复
引用 10 楼 jianggehappy01 的回复:
[quote=引用 9 楼 shihengzhen101 的回复:]
[quote=引用 6 楼 tfrist 的回复:]
按我上面说的代码改成这样
char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=0x%x,p2=0x%x\n", p1, p2);
printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
free(p1);
free(p2);
return 0;
}


它的输出结果可以看到,一个递增(堆)一个递减(栈中)

p1=0x740528,p2=0x74d420 //堆的地址
p1=0x4df864,p2=0x4df858 //栈的地址

这个方式挺好,可以是尝试一下
我的测试结果
p1=0x25d3c20,p2=0x25d3c90

p1=0x897f11a8,p2=0x897f11a0
说明堆递增、栈递减[/quote]

谢谢老哥,但是我用你代码怎么堆也是递减啊?栈是递减我知道。


#include "stdio.h"
#include "malloc.h"

char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=0x%x,p2=0x%x\n", p1, p2);
printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
free(p1);
free(p2);
return 0;
}
void main(void)
{
char *q=NULL;
q = str();//堆的生长方向????
}
[/quote]
楼上的解释比较详细,希望楼主仔细看看,堆的分配时递增的,这是指的顺序分配的情况,如果想楼上说的那样,在分配第二块内存时,刚好有一块能重复利用,那就会分配前一块,这种情况时,可以多分配几次内存,依次打印地址,我感觉总体应该是递增的
tfrist 2018-10-12
  • 打赏
  • 举报
回复
再多几句,比如excel表格中第一列,当堆内存是空的,malloc p1时第一表格A1给他,malloc p2时A2给他。p2必然大于p1. 也证明堆向搞地址递增。 如果开始申请的时候A1-A10都被使用中,那么malloc p1时,必然A11给他,之后A5表格free了,在申请p2时 A5的内存大小又满足100字节,A5返回给p2,此时p2必然小于p1。这是深层的分配机制问题。但并不能如此就说明堆不是向高地址增长的。不知是否说的很清楚了。按我说的做实验看看吧
tfrist 2018-10-12
  • 打赏
  • 举报
回复
引用 10 楼 jianggehappy01 的回复:
[quote=引用 9 楼 shihengzhen101 的回复:] [quote=引用 6 楼 tfrist 的回复:] 按我上面说的代码改成这样 char *str(void) { char *p1 = (char *)malloc(100);//堆区 char *p2 = (char *)malloc(100); printf("p1=0x%x,p2=0x%x\n", p1, p2); printf("p1=0x%x,p2=0x%x\n", &p1, &p2); free(p1); free(p2); return 0; } 它的输出结果可以看到,一个递增(堆)一个递减(栈中) p1=0x740528,p2=0x74d420 //堆的地址 p1=0x4df864,p2=0x4df858 //栈的地址
这个方式挺好,可以是尝试一下 我的测试结果 p1=0x25d3c20,p2=0x25d3c90 p1=0x897f11a8,p2=0x897f11a0 说明堆递增、栈递减[/quote] 谢谢老哥,但是我用你代码怎么堆也是递减啊?栈是递减我知道。
#include "stdio.h"
#include "malloc.h"

char *str(void)
{
	char *p1 = (char *)malloc(100);//堆区
	char *p2 = (char *)malloc(100);

	printf("p1=0x%x,p2=0x%x\n", p1, p2);
	printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
	free(p1);
	free(p2);
	return 0;
	}
void main(void)
{
	char *q=NULL;
	q = str();//堆的生长方向????
}
[/quote] 栈的分配没有异议。 我继续给你来解释堆是怎么回事,你的这个结果是可以理解的也是对的。 因为这要从内存分配机制讲。当申请堆的内存时有一个堆管理器回来处理你的内存分配请求,他会查看可用的内存块那个块可以满足你请求的大小。我们可以把堆想成是一些excel表格,它会从中找到一个空闲表格返回给你,也就是你malloc返回的。当你用完了不用了释放了free(),这个表格又变成空闲可用的了。这样的话其他的再申请的时候会优先的把这个空闲的返回。但是如果没有空闲的表格 那么堆管理器会在已用的表格的后面重新分配新表格给你。由此可见堆会在最下面创建新的空间,也就是内存地址最大,返回的地址是向下递增的。 你的这个情况应该是这样,当malloc p1时,堆管理器没有找到空闲的表格所以在最后(地址最大)新建了表格给你,之后在malloc p2之前,有一个之前使用着的表格free()了施放了,空闲了,这个时候你调用了malloc p2,当然会优先返回这个空闲的表格给你,当然这个地址比p1要小。也就是你的情况。当然这个空闲的表格得满足你的条件,即空闲的内存空间得小于或等于你要申请的内存大小。 而你申请的100个字节太小,稍微有表格(内存)被free释放都可以满足你的需求。 为了验证我的说法 你可以把p1 malloc大小不变,p2 malloc申请的大小增大比如到10000,让p1可以优先使用施放的空间,即使有施放的内存因为太小也不符合p2的要求,这样的话堆管理器必然会在最下面申请新的空间给p2,这样p2就会大于p1. 你试试看。这样你就堆有更深入的理解。
striveQiao 2018-10-12
  • 打赏
  • 举报
回复
引用 12 楼 tfrist 的回复:
再多几句,比如excel表格中第一列,当堆内存是空的,malloc p1时第一表格A1给他,malloc p2时A2给他。p2必然大于p1. 也证明堆向搞地址递增。 如果开始申请的时候A1-A10都被使用中,那么malloc p1时,必然A11给他,之后A5表格free了,在申请p2时 A5的内存大小又满足100字节,A5返回给p2,此时p2必然小于p1。这是深层的分配机制问题。但并不能如此就说明堆不是向高地址增长的。不知是否说的很清楚了。按我说的做实验看看吧

谢谢老哥,确实是你分析的这样。P1和P2两个都扩大100倍也能看到堆是递增的。
striveQiao 2018-10-12
  • 打赏
  • 举报
回复
引用 9 楼 shihengzhen101 的回复:
[quote=引用 6 楼 tfrist 的回复:]
按我上面说的代码改成这样
char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=0x%x,p2=0x%x\n", p1, p2);
printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
free(p1);
free(p2);
return 0;
}


它的输出结果可以看到,一个递增(堆)一个递减(栈中)

p1=0x740528,p2=0x74d420 //堆的地址
p1=0x4df864,p2=0x4df858 //栈的地址

这个方式挺好,可以是尝试一下
我的测试结果
p1=0x25d3c20,p2=0x25d3c90

p1=0x897f11a8,p2=0x897f11a0
说明堆递增、栈递减[/quote]

谢谢老哥,但是我用你代码怎么堆也是递减啊?栈是递减我知道。


#include "stdio.h"
#include "malloc.h"

char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=0x%x,p2=0x%x\n", p1, p2);
printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
free(p1);
free(p2);
return 0;
}
void main(void)
{
char *q=NULL;
q = str();//堆的生长方向????
}
AlbertS 2018-10-10
  • 打赏
  • 举报
回复
引用 6 楼 tfrist 的回复:
按我上面说的代码改成这样
char *str(void)
{
char *p1 = (char *)malloc(100);//堆区
char *p2 = (char *)malloc(100);

printf("p1=0x%x,p2=0x%x\n", p1, p2);
printf("p1=0x%x,p2=0x%x\n", &p1, &p2);
free(p1);
free(p2);
return 0;
}


它的输出结果可以看到,一个递增(堆)一个递减(栈中)

p1=0x740528,p2=0x74d420 //堆的地址
p1=0x4df864,p2=0x4df858 //栈的地址

这个方式挺好,可以是尝试一下
我的测试结果
p1=0x25d3c20,p2=0x25d3c90

p1=0x897f11a8,p2=0x897f11a0
说明堆递增、栈递减
啊大1号 2018-10-10
  • 打赏
  • 举报
回复
栈递减,堆递增
qq_40061236 2018-10-07
  • 打赏
  • 举报
回复
比较高深,看不懂
tfrist 2018-10-06
  • 打赏
  • 举报
回复
按我上面说的代码改成这样 char *str(void) { char *p1 = (char *)malloc(100);//堆区 char *p2 = (char *)malloc(100); printf("p1=0x%x,p2=0x%x\n", p1, p2); printf("p1=0x%x,p2=0x%x\n", &p1, &p2); free(p1); free(p2); return 0; } 它的输出结果可以看到,一个递增(堆)一个递减(栈中) p1=0x740528,p2=0x74d420 //堆的地址 p1=0x4df864,p2=0x4df858 //栈的地址
tfrist 2018-10-06
  • 打赏
  • 举报
回复
你的代码打印出来的是2个堆的空间的地址。要想看栈里面的地址需要改成这样 printf("p1=%d,p2=%d\n", &p1, &p2); 另外我建议你打印输出的时候别用%d,用16进制%x 比较好。
赵4老师 2018-10-04
  • 打赏
  • 举报
回复
现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录,输入程序名运行程序了!

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
Isnis-fallen 2018-10-04
  • 打赏
  • 举报
回复
就用你的代码, 那不是测试堆的 吗?
striveQiao 2018-10-04
  • 打赏
  • 举报
回复
引用 2 楼 focuslight的回复:
但我自己测出来确实和栈的生长方向一样是递增的 ----------------------------------- 栈的生长方向不是递增的 内存中的堆:队列优先,先进先出。向高地址扩展的数据结构 内存中的栈,是由系统自动分配和释放的,是由高地址向低地址扩展的数据机构
堆这个你怎么测的啊?测出来递增
Isnis-fallen 2018-10-04
  • 打赏
  • 举报
回复
但我自己测出来确实和栈的生长方向一样是递增的 ----------------------------------- 栈的生长方向不是递增的 内存中的堆:队列优先,先进先出。向高地址扩展的数据结构 内存中的栈,是由系统自动分配和释放的,是由高地址向低地址扩展的数据机构
性能测试是一个很有前途但又很没前途的职业,很有前途是因为做的好能带来高收益,能解决项目和系统的很多疑难问题,甚至是大问题(现实中有多少系统崩溃的悲惨案例,造成的损失很多时候让人承受不起),而优秀的性能测试工程师实在太稀缺了;但性能测试又很没前途,懂点软件测试的,都想拿着压力工具来试一把(然后说自己做过性能测试),实际又有多少公司常年有做不完的性能测试项目?市场需求量真有那么大吗?可以说,性能测试没前途,原因是因为我们当中很多人是半桶水,甚至连入门都不算,这样的人来做性能测试, 这项工作能有前途吗?所以,我们要改变,要让这个有价值的工作真正变成有前途(+钱途),要让性能测试不再是走过场,实打实的能解决问题,能给整个团队带来效益。讲师介绍:郑光华,网名smooth(CSDN上能看到我的博客),从事软件开发和测试工作15年,有多年的技术管理经验,现当任高级性能测试工程师 / 软件测试架构师,热爱性能测试和自动化测试工作,喜欢研究新技术,勤于总结,热于分享,希望通过培训课程输出自己的知识。课程内容:听完这个课程,你将会用不一样的视角,全面而系统的看待性能测试,从基础概念,到性能需求与设计,到性能测试工具原理,到性能监控及工具,到性能定位分析的掌握,都将会有完整而全新的认识,课程虽然不多,总共10节课(每节课25到40多分钟),但浓缩了很多性能测试知识的精华。课程重点是强调方法论和扩展思维视角(我们从思维的高度去理解和掌握性能测试,而不是从工具细节上去狭隘的了解性能测试工作),这个课程让初入性能测试的新人或是多年野蛮生长的老人,都能在思维和方法上更前进一步,为日后的项目工作提供有益帮助,在思想上向中、高级性能测试工程师看齐。现在就欢迎大家来接受洗脑吧,通过这个课程我们来完成一次性能测试知识的全面答疑和解惑。    本课程的整体知识结构如下图所示:

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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