未设置断点却触发中断?VSCode调试C程序异常求助
未设置断点却在free时触发VSCode调试中断的原因分析
调试时未手动设置任何断点,但程序在第二次输入校验时,会自动中断在free(within_max_value);语句处,需多次点击Continue才能继续:
- 程序运行时
max_value固定为11 - 首次输入数组:
int nums[11] = {0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9};,校验正常 - 第二次输入数组:
int nums[11] = {0, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10};,其中nums[1] = 11超出预期范围,触发中断
相关代码如下:
主程序调用校验逻辑:
/* Verify whether the entered value is each value between 1 and max_value */ while(checkForDuplicationForNums(key, key_length_m) /* Check whether the entered value is repeated */ || checkElemExceedsMax(key, key_length_m) || checkNumWithinMaxNotAppear(key, key_length_m)) { illegalInputPrompt(); getInputNumArrayByGetchHaveSpaces(key_string, key); }
触发中断的校验函数:
int checkForDuplicationForNums(int nums[], int max_value){ int* within_max_value = (int *)calloc(max_value, sizeof(int)); for(int i=0; i<max_value; i++) { /* nums : 0~m-1 */ within_max_value[nums[i]]++; } for(int i=0; i<max_value; i++) { if(within_max_value[i] > 1) { return 1; } } free(within_max_value); return 0; }
原因分析
核心问题是堆内存越界访问导致堆结构损坏,具体过程:
within_max_value通过calloc(max_value, sizeof(int))分配了11个int的内存,合法索引范围是0~10- 第二次输入的
nums[1] = 11,超出了within_max_value的合法索引范围,执行within_max_value[11]++时,会写入到堆内存的额外区域,破坏了堆的元数据(比如内存块的大小、链表指针等) - 堆结构损坏后,后续执行
free(within_max_value)时,内存管理器检测到堆异常,触发了VSCode调试器的自动中断(这是调试器默认开启的堆错误检测机制,无需手动设断点)
另外,主程序的校验顺序也有问题:checkForDuplicationForNums先于checkElemExceedsMax执行,导致越界的输入先进入了重复检测函数,直接触发内存错误。
修复建议
- 调整校验顺序:先执行
checkElemExceedsMax检查输入是否越界,再执行重复检测,避免越界数据进入内存操作逻辑 - 调整内存分配大小:如果允许输入值等于
max_value,则calloc的大小应设为max_value + 1,确保索引max_value合法 - 增加范围检查:在
checkForDuplicationForNums函数中,先校验nums[i]的范围,避免越界访问:for(int i=0; i<max_value; i++) { if(nums[i] < 0 || nums[i] >= max_value) { free(within_max_value); return 1; // 或根据业务逻辑返回对应错误码 } within_max_value[nums[i]]++; }
内容的提问来源于stack exchange,提问作者goon
相关产品推荐
相关产品推荐

