看看坛友中还有多少是和我一样长年战斗在 C 上的,答对三个就算

2018-09-25 17:36:23 +08:00
 dingzs3

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

void main()

{

    char *p1=(char *)malloc(1024);  //1k

    char *p2=(char *)malloc(4096);  //4k

    memset(p2,0,4096);

    char *p3=(char *)malloc(8192);  //8k

    char *p4=(char *)malloc(128*1024*1024); //128k

    char *p5=(char *)malloc(115*1024);//115k

    printf("p1=%p p2=%p p3=%p p4=%p p5=%p\n",p1,p2,p3,p4,p5);


    memset(p2,'1',20);

    free(p2);

    memset(p2,'y',10);

    printf("p2=%s\n",p2);

    free(p3); //core

    free(p5);

    free(p1);

}

输出: p1=0x1c60010 p2=0x1c60420 p3=0x1c61430 p4=0x7ffbabc2b010 p5=0x1c63440

p2=yyyyyyyyyy?

Segmentation fault (core dumped)

1.p2-p2 为啥不是 1024

2.p4 的地址为啥和其它的不一样

3.为啥在 free(p2)之后还能读写 p2

4.为啥 p2 的打印不是 yyyyyyyyyy1111111111

5.为啥在 free(p3)的时候会 core

8068 次点击
所在节点    程序员
76 条回复
andrewhxism
2018-09-25 17:40:33 +08:00
这代码写的。。。
zmj1316
2018-09-25 18:14:30 +08:00
考这种未定义行为不应该指定编译器和运行环境么......
innoink
2018-09-25 18:25:45 +08:00
你以为你在问 c 语言,其实你在问 libc 和操作系统
besto
2018-09-25 18:25:51 +08:00
0, void main 这波可以
1, 买看懂, p2-p2? p2-p1 可能是因为 fence memory
2,>128K malloc 会调用 mmap, 另外地址样式和编译器 甚至 32bit/64bit 都有关系
3, 没有说 free 过后就立刻不可用,甚至这是链表操作的一种偷懒形式
4, 这个其实还取决于编译器, 甚至可能只有 10 个 yy
5, 其实和 4 有关联,个人猜测是因为 free 之后,会修改一个链表值, free 之后再用 memset 把 p3 的数据破坏了.
easylee
2018-09-25 18:29:22 +08:00
手机上代码没有格式化,可阅读性非常差,不如利用一些贴代码网站。
zmj1316
2018-09-25 18:33:10 +08:00
根本不是考 C,都是操作系统的东西把。。。

1. malloc 会额外记录长度什么的数据,肯定不对齐的
2. 看 MMAP_THRESHOLD,超了就 mmap 去了
3. 虚拟内存按 page 分配,估计 p2 的那个 page 还在所以没抛异常
4.5 和操作系统内存分配链表有关,估计是写 p2 的时候把链表写坏了,VS 里面表现不一样,懒得看了
JeffKing
2018-09-25 18:40:32 +08:00
1. p2 为啥不是 1024?
不知道你在说什么

2.p4 的地址为啥和其它的不一样
p4 分配的地址过大,导致系统无法分配一整块内存

3.为啥在 free(p2)之后还能读写 p2
free 只是 free 了 p2 指向的 heap 空间,而 p2 本身没有置空,当然可以读写。只不过这时候是越界读写。

4.为啥 p2 的打印不是 yyyyyyyyyy1111111111
因为 p2 已结被 free 了,然后越界写入 y 10,当然是 yyyyyyyy

5.为啥在 free(p3)的时候会 core
p2 越界读写写到了 p3 的指针头地址,导致 free(p3)出错
iceheart
2018-09-25 18:43:32 +08:00
楼主注释写错了
innoink
2018-09-25 18:44:52 +08:00
@JeffKing 你这个基本都是错的
where2go
2018-09-25 18:45:33 +08:00
没有 void main() 这种写法, 后面没看
zhicheng
2018-09-25 18:48:32 +08:00
答案只有一个,未定义行为。
在未定义的前提下讨论代码行为没有任何意义。
catror
2018-09-25 18:50:17 +08:00
你问的是 ptmalloc(libc 里面的)的分配策略
fcten
2018-09-25 18:50:27 +08:00
只要我换一个内存分配的实现,你的问题可能都不成立。
JeffKing
2018-09-25 18:51:20 +08:00
@innoink 那麻烦大佬用清晰的解释打醒我(手动微笑)
GeruzoniAnsasu
2018-09-25 19:27:09 +08:00
你以为你在问 C
我以为你在问 CTF 题怎么做
lance6716
2018-09-25 20:33:32 +08:00
mark,等答案
yulon
2018-09-25 20:50:48 +08:00
看见 void main 就不想看了
huluhulu
2018-09-25 21:06:06 +08:00
void main 很正常……
zwh2698
2018-09-25 21:07:38 +08:00
敢问兄弟写了几年?另外兄弟 c 中可以存任意基本类型的类型是什么?
zwh2698
2018-09-25 21:18:54 +08:00
还有兄弟你的问题就是问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/492448

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX