作者Petyr (小指头)
看板C_and_CPP
标题[问题] 关於free()这个函数的使用
时间Mon Aug 21 01:46:37 2017
小弟程式算是新手
最近遇到一个很头大的 free() invaild pointer 的bug
也爬过有关於free的文章百思不得其解
想来请教一下各位前辈
程式码大略是这样的
--
--
char *a
char *b //以上这里是在func里宣告两个pointer
--
--
--
while (某个结束条件)
{
--
--
--
--
if {
里面执行的程式码称作A
跟上面的两个pointer没有关系
}
else {
里面执行的程式码称作B
a = malloc(xxx) //在这边配置记忆体位置给这两个pointer
b = malloc(xxx)
--
--
--
free(b) // b使用结束 free掉
--
--
free(a) // a使用结束 free掉
}
} //while 结束
架构大致上如以上,
在while里会有A及B任意合(Ex: 可能执行两次A再执行一次B然後跳出回圈之类,
问题来了 :
Q: 只要我是执行B不管执行几次最後再执行A,程式都不会有任何问题
但只要A在B之前先执行过,执行B的时候,要free(b)就会出现
free():invaild pointer的错误,但A理论上跟那两个pointer完全没有关系啊~
以上,卡了很久,请大家帮帮忙了QAQ
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.177.108.225
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1503251200.A.E30.html
1F:→ Schottky: 合理怀疑是 buffer overflow,问题出在你没写明之处 08/21 01:50
我一开始有怀疑是array超出范围的问题仔细检查过每个array,
不过看起来没有什麽大问题,谢谢你的建议我会在找找看 :)
※ 编辑: Petyr (180.177.108.225), 08/21/2017 01:52:16
2F:→ Schottky: 检查 A 段程式是否意外覆盖了这两个变数 08/21 01:51
3F:推 FRAXIS: 在 b malloc 的时候先印出来记忆体位置 08/21 02:41
4F:→ FRAXIS: 然後在 free b 的时候确认是不是同一个位置 08/21 02:41
5F:→ FRAXIS: 如果不一样 那代表变数被改变过了 08/21 02:42
6F:→ FRAXIS: 如果一样 那可能是重复 free 或是 malloc 本身的资讯 08/21 02:43
7F:→ FRAXIS: 已经被搞坏了.. 08/21 02:43
8F:推 winken2004: malloc a b之後 先确定ab不是null吧 08/21 03:15
9F:→ winken2004: if(a == NULL) assert("error"); 08/21 03:16
10F:→ winken2004: 然後自己加一些debug讯息判断一下发生甚麽事 08/21 03:16
11F:推 mike0227: free(NULL);是合法的。pointer一定被动到或是没malloc 08/21 03:58
12F:推 steve1012: Free 完把ptr 指到null 才是好习惯 建议先改了以後看 08/21 04:47
13F:→ steve1012: 中间是不是有哪里改到 08/21 04:47
14F:推 steve1012: 然後建议你抽出有问题的片段 贴可以重现bug 的程式上 08/21 04:51
15F:→ steve1012: 来 08/21 04:51
16F:→ steve1012: 一开始宣告没要马上用的话 最好也指到null 较容易debug 08/21 04:52
17F:推 steve1012: 话说a用不到pointer 为啥不在b里面宣告? 08/21 05:51
18F:推 b0920075: 我比较倾向於overflow造成chunk的info被动到,这样有没 08/21 08:16
19F:→ b0920075: 有设成null应该都会出错 08/21 08:16
20F:推 b0920075: 当然pointer被改掉也是很有可能 08/21 08:52
21F:→ descent: 你先把 char *a, char *b 改成全域变数来宣告, 08/21 17:08
22F:→ descent: 看看是否正常? 08/21 17:08
23F:推 jerryh001: 贴原始code吧 不然只能搬水晶球了 08/21 17:13
24F:→ Lipraxde: 不知到关掉优化会不会有影响 08/21 17:40
25F:嘘 grayStone: source code 08/21 17:42
26F:→ stucode: 即使简化 建议至少要贴「最小可重现问题的程式码」 08/21 20:47
27F:→ stucode: 这可以训练你发现问题的能力 有时甚至会直接解决 08/21 20:48
28F:→ enonrick: 楼上们超强的,一点像样的snippet都没有也讨论得起来 08/21 23:48
29F:推 CoNsTaR: 其实楼主如果有能力找到最小可重现问题的程式码的话,那 08/22 01:56
30F:→ CoNsTaR: 他其实也不用上来问了 08/22 01:56
31F:→ Schottky: @enonrick 我们上次有团购压克力水晶球 08/22 02:08
32F:推 steve1012: 好好奇啊 要是原po真的很害羞的话可以私我我帮你看 08/22 04:20
33F:→ steve1012: 再帮你抽出有问题的地方贴上来 08/22 04:28
34F:→ linotwo: a b 变数直接宣告在 B 的 scope 里面比较好 08/23 04:40
35F:→ linotwo: 有可能是 A 里面有地方去非法覆盖到 heap 资讯 08/23 04:45
36F:→ tinlans: 很多实作是把配置资讯黏在 malloc() 传回位址之前,如果 08/25 12:11
37F:→ tinlans: 那块空间被当阵列存取,索引值不小心是负值时就可能把它 08/25 12:11
38F:→ tinlans: 盖掉,然後 free() 就会认为这块空间之前没配置过。 08/25 12:12