为什么_stprintf_s会覆盖其他变量,但_stprintf不是?

gta*_*atr 3 c++ malloc winapi printf

我正在使用visual studio for win32编程类.我有一个全局数组的字符串声明TCHAR **bufTh在内存中分配,如

bufTh = (TCHAR**)malloc(nOfTh*sizeof(TCHAR*));
for (i = 0; i < nOfTh; i++)
    bufTh[i] = (TCHAR*)malloc(BUF_LEN*sizeof(TCHAR));
Run Code Online (Sandbox Code Playgroud)

然后我有一些线程,每个线程在这个数组中写入不同的字符串.我注意到,如果我使用_stprintf_s(bufTh[iTh], BUF_LEN, _T("%s\\"), findData.cFileName);,在这个操作之后,其他一些全局变量(在我的情况下是信号量)被覆盖,而如果我使用_stprintf(没有_s)一切顺利.

为什么?我哪里错了?

我也尝试过使用包含字符串的struct数组,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;
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 5

在我的运行中,信号量被覆盖为值0xfefefefe

这是一个"神奇的值",它由安全的CRT函数(如_stprintf_s)编写,以帮助您调试传递的缓冲区长度中的错误.这些函数的调试版本使用0xfe作为填充值填充整个缓冲区.

   _stprintf_s(bufTh[i], BUF_LEN, ...));
Run Code Online (Sandbox Code Playgroud)

所以,你什么知道的是,thBuf的缓冲区大小[0]是不是其实BUF_LEN.换句话说,malloc()调用不正确.

   #define BUF_LEN _MAX_PATH+1
Run Code Online (Sandbox Code Playgroud)

这是一个邪恶的宏,并导致你的问题.它扩展到

   bufTh[i] = (TCHAR*)malloc(_MAX_PATH + 1*sizeof(TCHAR));
Run Code Online (Sandbox Code Playgroud)

当然不是你的意思.固定:

   #define BUF_LEN (_MAX_PATH+1)
Run Code Online (Sandbox Code Playgroud)

额外的括号是至关重要的.否则是开始使用const关键字的一个很好的理由.