C语言调用free()释放内存报错,二进制数插入逗号功能问题排查
C语言二进制字符串插入逗号函数free报错问题
我尝试编写一个为二进制数插入逗号的函数,以下是我的实现方案:代码在不调用free()释放内存时可正常运行,一旦调用free()就会报错,我无法定位问题原因,烦请告知哪里出错了。
问题代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int insertCommasIntoBinaryNumber(char* outstring, char* instring) { char *ptr, *optr; int i, length, commas; // move ptr to end of instring for ( ptr = instring; *ptr; ptr++ ); //calculate offset with commas length = ptr - instring; commas = ( length - 1 ) / 8; optr = outstring + length + commas; //copy instring into outstring backwards inserting commas *optr-- = *ptr--; for ( i = 1; ptr >= instring; i++ ) { *optr-- = *ptr--; if ( ( i % 8 ) == 0 ) *optr-- = ','; } } int main (void) { const int arrayDimension = 100; char* instring = (char*) malloc(sizeof(char) * arrayDimension); char* outstring = (char*) malloc(sizeof(char) * arrayDimension); strncpy(instring, "111111110101010100001100", arrayDimension-1); insertCommasIntoBinaryNumber(outstring, instring); /* show the result */ printf ( "%s\n", outstring ); free(instring); free(outstring); }
运行报错信息
11111111,01010101,00001100 *** Error in `./a.out': free(): invalid next size (fast): 0x0000000000bc8010 ***
问题原因
报错的核心原因是缓冲区溢出破坏了malloc的内存块头部信息:
- 测试用的二进制输入字符串长度为24,按每8位插1个逗号的规则,实际只需要插入2个逗号,但原始代码的插入逻辑在i=8、16、24时都会触发逗号插入,一共插入3个逗号
- 提前计算的输出缓冲区偏移没有预留多插入的逗号位置,导致写入操作越界到了malloc分配的内存块外,破坏了内存块的头信息,
free()校验到头部异常就会抛出错误
修复后可运行代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> int insertCommasIntoBinaryNumber(char* const outString, const char* const inString) { char const *iptr; // iptr指向常量输入字符串 char *optr; int i, commaCount; // 移动iptr到输入字符串末尾 for ( iptr = inString; *iptr; iptr++ ); // 计算需要插入的逗号数量 const int inStringLength = iptr - inString; const double totalNumberOfCommasFP = (( inStringLength ) / 8.0) - 1.0; const int totalNumberOfCommas = (int) ceil(totalNumberOfCommasFP); // 设置输出指针起始位置 optr = outString + inStringLength + totalNumberOfCommas; // 倒序复制输入字符串到输出缓冲区,同时插入逗号 *optr-- = *iptr--; commaCount = 0; for ( i = 1; iptr >= inString; i++ ) { *optr-- = *iptr--; // 插入逗号前校验逗号数量不超过上限 if ( ( ( i % 8 ) == 0 ) && (commaCount < totalNumberOfCommas) ) { *optr-- = ','; commaCount++; } } } int main (void) { const char testString[] = "111111110101010100001100"; const int inStringArrayDimension = strlen(testString) + 1; char * inString = (char*) malloc(sizeof(char) * inStringArrayDimension); strncpy(inString, testString, inStringArrayDimension); const int inStringLength = (int) strlen(inString); const double totalNumberOfCommasFP = (( inStringLength ) / 8.0) - 1.0; const int totalNumberOfCommas = (int) ceil(totalNumberOfCommasFP); // 根据输入长度和逗号数量精确计算输出缓冲区大小 const int outStringArrayDimension = inStringArrayDimension + totalNumberOfCommas; char* outString = (char*) malloc(sizeof(char) * outStringArrayDimension); insertCommasIntoBinaryNumber(outString, inString); /* 输出结果 */ printf ( "%s\n", outString ); free(inString); free(outString); exit (EXIT_SUCCESS); }
修复后运行结果
11111111,01010101,00001100
内容的提问来源于stack exchange,提问作者RobK
相关产品推荐
相关产品推荐

