堆得生长方向问题

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地址递减了
}
...全文
874 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语言指针与汇编内存地址-一.代码要素
Arnis1973 2018-10-04
  • 打赏
  • 举报
回复
就用你的代码, 那不是测试堆的 吗?
striveQiao 2018-10-04
  • 打赏
  • 举报
回复
引用 2 楼 focuslight的回复:
但我自己测出来确实和栈的生长方向一样是递增的 ----------------------------------- 栈的生长方向不是递增的 内存中的堆:队列优先,先进先出。向高地址扩展的数据结构 内存中的栈,是由系统自动分配和释放的,是由高地址向低地址扩展的数据机构
堆这个你怎么测的啊?测出来递增
Arnis1973 2018-10-04
  • 打赏
  • 举报
回复
但我自己测出来确实和栈的生长方向一样是递增的 ----------------------------------- 栈的生长方向不是递增的 内存中的堆:队列优先,先进先出。向高地址扩展的数据结构 内存中的栈,是由系统自动分配和释放的,是由高地址向低地址扩展的数据机构

33,311

社区成员

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

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