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

Why does the given code throw a heap corruption error?

以下代码在尝试释放 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);

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

但是,请记住 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 总是故意在 len 字符处以 NUL 终止缓冲区,以确保缓冲区始终以 NUL 终止,并使这些潜在的错误变得明显。