我有问题。我正在为char*
分配空间,但是当我尝试free
空间时,我的程序崩溃了。
这是代码
fullPath = (char *) malloc(strlen(path) + strlen(fileData->d_name) + 1);
if (fullPath == NULL)
{
handleErrors(ERR_ALOCATION_CODE);
}
sprintf(fullPath, "%s/%s", path, fileData->d_name);
//... some more code, I only use fullPath, I don't change it here
free(fullPath);
尝试free
时,上面的代码失败了。我将不胜感激。
答案 0 :(得分:5)
您没有为终止NUL字符的字符串分配空间。所以改变分配:
// allocate memory for 1st part, slash, 2nd part and terminating NUL char
fullPath = malloc(strlen(path) + 1 + strlen(fileData->d_name) + 1);
另请注意,在C语言中,转换malloc
的返回值是不好的做法,所以我删除了它。
如果您计算错误的长度,使用snprintf
可能会有所改进,但在这种情况下可能是一个意见问题。无论如何,代码将成为
// size for 1st part, slash, 2nd part and terminating NUL char
size_t bufsize = strlen(path) + 1 + strlen(fileData->d_name) + 1;
fullPath = malloc(bufsize);
//...
snprintf(fullPath, bufsize, "%s/%s", path, fileData->d_name);
然后一个错误不会导致未定义的行为,而是生成从末尾切断的字符的路径。这是一个比随机崩溃更好的错误情况(例如文件未找到错误),更不用说调试了,当你可以打印文件名并看看它是不对的时候。
一些解释:在问题代码中,因为您分配的字节太少,导致缓冲区过低,这是未定义的行为,所以基本上任何事情都可能发生。对于1字节缓冲区溢出,很可能不会发生任何不良情况,因为可能在分配结束时未使用的字节。所以在某种程度上你很幸运能够如此早地抓住这一点。你可以想象找到一个bug是多么困难,当程序崩溃时只有字符串长度是16的精确倍数并且工作正常...幸运的是有一些工具可以检测这样的东西,但最好的防御是成为一个迂腐的C程序员,谁努力写出好的代码......