为什么给定的代码会抛出堆损坏错误?
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 终止,并使这些潜在的错误变得明显。
以下代码在尝试释放 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 终止,并使这些潜在的错误变得明显。