问个简单的问题--堆栈的内存分配方式

小小蔷薇 2011-12-06 10:42:01
char a[8] ={0};
int i =0;
int j =0;
char b[8] ={0};
char c[] ="alkjshgjriwjlkgndklsngwrgv";
memcpy(b,c,sizeof(c));
printf("%s",a);输出什么

这个题目考察的是不是,栈是从下向上使用的?
如果是堆的分配就是从上向下使用?
...全文
185 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
小小蔷薇 2011-12-13
  • 打赏
  • 举报
回复
谢谢!
mymsdndownload 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 zhll879 的回复:]
char a[8] ={0};
int i =0;
int j =0;
char b[8] ={0};
char c[] ="alkjshgjriwjlkgndklsngwrgv";
memcpy(b,c,sizeof(c));
printf("%s",a);输出什么

这个题目考察的是不是,栈是从下向上使用的?
如果是堆的分配就是从上向下使用?
[/Quote]
基于以下三个假定:1)你是在一个x86系统 2)编译器保证栈分配是连续的 3)编译器无深度优化
显然此时地址从小到大是 b j i a
此时再假定int 是4个字节 char 占1个字节
memcpy后,b因为只有8个字节,故只能存放alkjshgj
剩下的必须溢出到j i a
j四个字节 存放riwj i四个字节 存放lkgn
a 8个字节 存放dklsngwr
至于剩下的gv和'\0' 只好覆盖到后面的地址了
那么后面的地址存的是什么呢?我们知道通常的编译器不做优化的时候,会上来push ebp
这个地址通常是0x0012FFXX 在intel x86下小端存储 就是 XX FF 12 00
所以此处覆盖后 情况就是 'g' 'v' 00 00
以%s打印a之后,结果依赖什么时候找到0 显然 会在gv后面找到0
这样打印结果就是dklsngwrgv 但是在程序结束处 ebp被覆盖 导致无法正常结束 因此可能会暴异常
hishopsoft 2011-12-07
  • 打赏
  • 举报
回复
我在dos下的tc 2.0测试这个程序,输出的是一个空字符串。
通过debug查看,发现这些变量并不是一个一个push到栈中的,而是用直接将栈的栈顶往上移动30h个字节,
然后将变量的值从低到高填充的栈中。而不是我们设想的先定义的变量在栈的高位。

这一段程序执行后,他们在内存的排列如下
0BF9:FFB0 E8 FF 40 02 B9 0A 0D 04-00 00 00 00 00 00 00 00 ?@.?..........
0BF9:FFC0 00 00 00 00 00 00 00 00-00 00 00 00 61 6C 6B 6A ............alkj
0BF9:FFD0 73 68 67 6A 72 69 77 6A-6C 6B 67 6E 64 6B 6C 73 shgjriwjlkgndkls
0BF9:FFE0 6E 67 77 72 67 76 00 0A-F4 FF 1D 01 01 00 F2 FF ngwrgv..?....?
其中第一行和第二行,共20个字节的00就是
char a[8] ={0};
int i =0;
int j =0;
char b[8] ={0};
这些变量分配的(8+2+2+8=20,我这个是在dos测试的,int是16位,也就是2个字节)
我们看到,先声明的在低位,后声明的在高位。
当我们执行memcpy(b,c,sizeof(c));后看内存的情况:
0BF9:FFB0 0D 04 C4 FF CC FF 1B 00-00 00 00 00 00 00 00 00 ..??..........
0BF9:FFC0 00 00 00 00 61 6C 6B 6A-73 68 67 6A 72 69 77 6A ....alkjshgjriwj
0BF9:FFD0 6C 6B 67 6E 64 6B 6C 73-6E 67 77 72 67 76 00 73 lkgndklsngwrgv.s
0BF9:FFE0 6E 67 77 72 67 76 00 0A-F4 FF 1D 01 01 00 F2 FF ngwrgv..?....?
0BF9:FFF0 82 05 F6 FF 00 00 54 32-2E 45 58 45 00 00 FB 00 ??..T2.EXE..?
复制后,它占用了char b的8个字节的空间,然后又将自己的一部分空间给占用了,并没有占用到
char a的空间,所以a会原样输出。

我这个是在dos下的tc 2.0编译后用debug测试调试的,可能其它的编译器不是这样运作的,手头没有windows下的c编译器。。没办法测试其它的,请大家自行调试看看。
mosal 2011-12-06
  • 打赏
  • 举报
回复
求分 哈哈
qwer_boo 2011-12-06
  • 打赏
  • 举报
回复
memcpy这里肯定会出问题,考察目的应该是字符串的问题,是不是以'\0'结尾.
薛定谔之死猫 2011-12-06
  • 打赏
  • 举报
回复
栈上变量的摆放~
mosal 2011-12-06
  • 打赏
  • 举报
回复
跟踪下地址就都清楚了
自信男孩 2011-12-06
  • 打赏
  • 举报
回复
乱码是没有字符串的结束符的原因,就是'\0'。
自信男孩 2011-12-06
  • 打赏
  • 举报
回复
能够输出结果,但是会有乱码。alkjshgj后面是乱码。堆和栈是分开的。
机智的呆呆 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhll879 的回复:]
那这段程序输出的结果是不确定的?
[/Quote]
未定义行为,严重依赖编译器和运行环境。
jisuanji1bo 2011-12-06
  • 打赏
  • 举报
回复
这个问题不懂,有谁能够给出详细的回答
小小蔷薇 2011-12-06
  • 打赏
  • 举报
回复
那这段程序输出的结果是不确定的?
机智的呆呆 2011-12-06
  • 打赏
  • 举报
回复
从大部分实现来看,栈是往低地址延伸的,后声明的变量处在地地址~~
另外变量之间不一定是紧挨着的
AnYidan 2011-12-06
  • 打赏
  • 举报
回复
拷的是 纠错,没有人敢保证 stack 上的变量是连续的
小小蔷薇 2011-12-06
  • 打赏
  • 举报
回复
http://apps.hi.baidu.com/share/detail/49739018
「已注销」 2011-12-06
  • 打赏
  • 举报
回复
gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
gcc test.c
./a.out
dklsngwrgv
yxl_2011_8_5 2011-12-06
  • 打赏
  • 举报
回复
这个题目确实是考察栈的存储方式。
如果是堆的话,分配内存是随机分配的,根本不存在连续性,所以更说不上是从上向下使用。
x90386 2011-12-06
  • 打赏
  • 举报
回复
Access Violation……
clleady 2011-12-06
  • 打赏
  • 举报
回复
我猜测,输出dklsngwr,现在没这个环境,没法做实验看。

这题考验的是内存分配。
他分配了一段连续的空间,然后c中内容复制到b中后,那些溢出的数据正好覆盖了i,j和a变量分配的空间。

69,371

社区成员

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

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