为什么 _stprintf_s 会覆盖其他变量但 _stprintf 不会?
Why is _stprintf_s overwriting other variables but _stprintf is not?
我正在使用 visual studio 进行 win32 编程 class。我在内存中分配了一个声明为 TCHAR **bufTh
的全局字符串数组,如
bufTh = (TCHAR**)malloc(nOfTh*sizeof(TCHAR*));
for (i = 0; i < nOfTh; i++)
bufTh[i] = (TCHAR*)malloc(BUF_LEN*sizeof(TCHAR));
然后我有一些线程,每个线程都写入此数组中的不同字符串。我注意到如果我使用 _stprintf_s(bufTh[iTh], BUF_LEN, _T("%s\"), findData.cFileName);
,在此操作之后,其他一些全局变量(在我的例子中是信号量)被覆盖,而如果我使用 _stprintf
(没有 _s)一切顺利。
为什么?我哪里错了?
我还尝试使用包含字符串的结构数组作为实验,例如 typedef struct{TCHAR buf[BUF_LEN];} mystr_t;
,然后分配 bufTh = (mystr_t*)malloc(nOfTh*sizeof(mystr_t));
。在这种情况下,_stprintf_s
按预期工作,没有问题。
编辑:这是一个 mcve
#define UNICODE
#define _UNICODE
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NON_CONFORMING_SWPRINTFS
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#define BUF_LEN _MAX_PATH+1
typedef struct{
DWORD iTh;
} tdata_t;
TCHAR **bufTh;
PHANDLE sem;
//DWORD WINAPI rThread(LPVOID pThParam);
int _tmain(int argc, LPTSTR argv[]){
DWORD i, nOfTh;
PHANDLE hthread;
tdata_t *tdata;
nOfTh = 1;
// global array of buffers, one for each reading thread
bufTh = (TCHAR**)malloc(nOfTh*sizeof(TCHAR*));
for (i = 0; i < nOfTh; i++)
bufTh[i] = (TCHAR*)malloc(BUF_LEN*sizeof(TCHAR));
// array of thread data, to pass to threads
tdata = (tdata_t*)malloc(nOfTh*sizeof(tdata_t));
for (i = 0; i < nOfTh; i++){
tdata[i].iTh = i;
}
// array of semaphores, one for each thread
sem = (PHANDLE)malloc((nOfTh)*sizeof(HANDLE));
for (i = 0; i < nOfTh; i++)
sem[i] = CreateSemaphore(NULL, 0, 1, NULL);
// array of threads
/*hthread = (PHANDLE)malloc(nOfTh*sizeof(HANDLE));
for (i = 0; i < nOfTh; i++)
hthread[i] = CreateThread(NULL, 0, &rThread, (LPVOID)&tdata[i], 0, NULL);*/
i = 0;
// BREAKPOINT HERE
_stprintf_s(bufTh[i], BUF_LEN, _T("%s\"), _T("the string that I want to write there"));
// BREAKPOINT HERE
WaitForSingleObject(sem[i], INFINITE);
//WaitForMultipleObjects(nOfTh, hthread, TRUE, INFINITE);
system("pause");
return 0;
}
also in my runs semaphores are overwritten with value 0xfefefefe
这是一个"magic value",它是由安全CRT函数(如_stprintf_s)编写的,以帮助您调试您传递的缓冲区长度中的错误。这些函数的调试版本填充整个缓冲区,使用 0xfe 作为填充值。
_stprintf_s(bufTh[i], BUF_LEN, ...));
所以你知道的是thBuf[0]的缓冲区大小实际上不是BUF_LEN。换句话说,malloc() 调用不正确。
#define BUF_LEN _MAX_PATH+1
这是一个邪恶的宏,会导致您的问题。它扩展到
bufTh[i] = (TCHAR*)malloc(_MAX_PATH + 1*sizeof(TCHAR));
当然不是你的意思。修复:
#define BUF_LEN (_MAX_PATH+1)
额外的括号很重要。否则是开始使用 const
关键字的一个很好的理由。
我正在使用 visual studio 进行 win32 编程 class。我在内存中分配了一个声明为 TCHAR **bufTh
的全局字符串数组,如
bufTh = (TCHAR**)malloc(nOfTh*sizeof(TCHAR*));
for (i = 0; i < nOfTh; i++)
bufTh[i] = (TCHAR*)malloc(BUF_LEN*sizeof(TCHAR));
然后我有一些线程,每个线程都写入此数组中的不同字符串。我注意到如果我使用 _stprintf_s(bufTh[iTh], BUF_LEN, _T("%s\"), findData.cFileName);
,在此操作之后,其他一些全局变量(在我的例子中是信号量)被覆盖,而如果我使用 _stprintf
(没有 _s)一切顺利。
为什么?我哪里错了?
我还尝试使用包含字符串的结构数组作为实验,例如 typedef struct{TCHAR buf[BUF_LEN];} mystr_t;
,然后分配 bufTh = (mystr_t*)malloc(nOfTh*sizeof(mystr_t));
。在这种情况下,_stprintf_s
按预期工作,没有问题。
编辑:这是一个 mcve
#define UNICODE
#define _UNICODE
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NON_CONFORMING_SWPRINTFS
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#define BUF_LEN _MAX_PATH+1
typedef struct{
DWORD iTh;
} tdata_t;
TCHAR **bufTh;
PHANDLE sem;
//DWORD WINAPI rThread(LPVOID pThParam);
int _tmain(int argc, LPTSTR argv[]){
DWORD i, nOfTh;
PHANDLE hthread;
tdata_t *tdata;
nOfTh = 1;
// global array of buffers, one for each reading thread
bufTh = (TCHAR**)malloc(nOfTh*sizeof(TCHAR*));
for (i = 0; i < nOfTh; i++)
bufTh[i] = (TCHAR*)malloc(BUF_LEN*sizeof(TCHAR));
// array of thread data, to pass to threads
tdata = (tdata_t*)malloc(nOfTh*sizeof(tdata_t));
for (i = 0; i < nOfTh; i++){
tdata[i].iTh = i;
}
// array of semaphores, one for each thread
sem = (PHANDLE)malloc((nOfTh)*sizeof(HANDLE));
for (i = 0; i < nOfTh; i++)
sem[i] = CreateSemaphore(NULL, 0, 1, NULL);
// array of threads
/*hthread = (PHANDLE)malloc(nOfTh*sizeof(HANDLE));
for (i = 0; i < nOfTh; i++)
hthread[i] = CreateThread(NULL, 0, &rThread, (LPVOID)&tdata[i], 0, NULL);*/
i = 0;
// BREAKPOINT HERE
_stprintf_s(bufTh[i], BUF_LEN, _T("%s\"), _T("the string that I want to write there"));
// BREAKPOINT HERE
WaitForSingleObject(sem[i], INFINITE);
//WaitForMultipleObjects(nOfTh, hthread, TRUE, INFINITE);
system("pause");
return 0;
}
also in my runs semaphores are overwritten with value 0xfefefefe
这是一个"magic value",它是由安全CRT函数(如_stprintf_s)编写的,以帮助您调试您传递的缓冲区长度中的错误。这些函数的调试版本填充整个缓冲区,使用 0xfe 作为填充值。
_stprintf_s(bufTh[i], BUF_LEN, ...));
所以你知道的是thBuf[0]的缓冲区大小实际上不是BUF_LEN。换句话说,malloc() 调用不正确。
#define BUF_LEN _MAX_PATH+1
这是一个邪恶的宏,会导致您的问题。它扩展到
bufTh[i] = (TCHAR*)malloc(_MAX_PATH + 1*sizeof(TCHAR));
当然不是你的意思。修复:
#define BUF_LEN (_MAX_PATH+1)
额外的括号很重要。否则是开始使用 const
关键字的一个很好的理由。