为什么给定的代码会抛出堆损坏错误?

时间:2016-06-26 16:03:10

标签: c string heap-corruption

以下代码在尝试释放lpSubKey时会引发堆损坏。

到底出了什么问题?

#define DRIVER_NAME L"TEST"
#define SUB_KEY     L"System\\CurrentControlSet\\Services\\"

size_t len = (wcslen(SUB_KEY) + wcslen(DRIVER_NAME) + 1) * sizeof(WCHAR);
LPWSTR lpSubKey = calloc(1, len);

wcscat_s(lpSubKey, len, SUB_KEY);
wcscat_s(lpSubKey, len, DRIVER_NAME);

free(lpSubKey);

编辑:即使这是main()中唯一的代码,也会抛出错误,因此错误不会发生在其他地方。

EDIT2:更新代码以反映已接受的答案已解决了问题。我仍然不知道为什么首先出现错误。即使wcscat_s没有提供保护,因为len没有正确的值,我的缓冲区应该足够大以容纳两个字符串。

#define DRIVER_NAME L"TEST"
#define SUB_KEY     L"System\\CurrentControlSet\\Services\\"

size_t len = wcslen(SUB_KEY) + wcslen(DRIVER_NAME) + 1;
LPWSTR lpSubKey = calloc(len, sizeof(WCHAR));

wcscat_s(lpSubKey, len, SUB_KEY);
wcscat_s(lpSubKey, len, DRIVER_NAME);

free(lpSubKey);

1 个答案:

答案 0 :(得分:1)

这里没有任何特定错误的证据(你分配的字符串足够大),所以问题可能在其他地方。

但是,请记住wcscat_s需要个元素,而不是缓冲区的大小,因此此处的_s版本的C函数不会保护您以任何方式。一种更连贯的工作方式(len包含字符数,而不是字节)可能是:

size_t len = (wcslen(SUB_KEY) + wcslen(DRIVER_NAME) + 1);
LPWSTR lpSubKey = calloc(len, sizeof(WCHAR));

wcscat_s(lpSubKey, len, SUB_KEY);
wcscat_s(lpSubKey, len, DRIVER_NAME);

free(lpSubKey);

<强> 更新

鉴于修复此问题已解决问题,我怀疑wcscat_s始终故意NUL-终止len字符处的缓冲区,以确保缓冲区始终以NUL终止,并且使这些潜在的错误显而易见。