函数二次调用触发Double free or corruption错误的排查求助
首先咱们拆解下你的问题:你写的getCount函数第一次调用完全正常,但第二次调用就触发了"Double free or corruption"错误,你尝试给malloc加1(虽然这里存的不是字符串)但没用,还困惑为什么函数里free后的局部指针没出作用域,重新malloc还会出问题。
先看你的代码,函数里的allDigits是局部变量,每次调用函数都会重新声明、重新malloc,第一次调用结束后free并置为NULL,这个指针本身会随着函数返回销毁,第二次调用是全新的指针,理论上不该出现double free。那问题大概率出在堆内存被破坏了,而不是真的double free。
问题根源:数组越界访问破坏堆结构
你的代码没有处理负数输入的情况!比如当传入number = -123时,number % 10在C语言里会返回负数(比如-123 % 10结果是-3),这时候你执行allDigits[currentDigit] = true,相当于访问allDigits[-3]——这是严重的数组越界,会直接覆盖堆内存的元数据(malloc用来管理内存的信息)。
第一次调用时,堆破坏可能没有立刻触发错误,但第二次调用malloc或者free时,系统检测到堆结构异常,就会抛出"Double free or corruption"这类错误(看起来像是double free,但实际是堆被破坏导致的误报)。
修复方案
只需要在处理数字前,把输入转换成非负数即可,用abs()函数(记得包含<stdlib.h>头文件):
#include <stdlib.h> // 要包含这个头文件才能用abs() #include <string.h> // 用于memset初始化内存 int getCount(int number) { int totalUniqueDigits = 0; // 先把负数转换成正数,避免取模得到负数下标 number = abs(number); bool* allDigits = (bool*)malloc(10 * sizeof(bool)); // 额外建议:malloc的内存要初始化,避免脏数据影响统计 memset(allDigits, 0, 10 * sizeof(bool)); do { int currentDigit = number % 10; number /= 10; allDigits[currentDigit] = true; } while (number > 0); for (int i = 0; i < 10; i += 2) { if (allDigits[i] == true) { totalUniqueDigits++; } } free(allDigits); allDigits = NULL; return totalUniqueDigits; }
另外补充一个小建议:malloc出来的内存是未初始化的,里面是随机的脏数据,最好用memset把它初始化为0,避免某些极端情况(比如输入是0时,do-while循环不执行,allDigits[0]还是脏数据,可能导致统计错误)。
为什么之前加1没用?
你尝试给malloc加1是针对字符串的逻辑(因为字符串需要额外存终止符),但这里是bool数组,10个元素刚好是10*sizeof(bool),加1反而会多分配内存,但根本问题是数组越界,所以这个操作解决不了问题。
内容的提问来源于stack exchange,提问作者Patrick

