0

我需要一个提供 LPTSTR 和枚举值的函数,根据该值构造一个字符串并将其放入 LPTSTR。

我编写了以下函数,它使用由枚举值索引的名称数组:

bool GetWinClassName(const int &WinType, LPTSTR *className, const int bufSize)
{
    bool allOk = true;
    LPTSTR tempName = new TCHAR[bufSize];
    _stprintf_s(tempName, bufSize, TEXT("Win%sClass"), g_WinNames[WinType]);
    std::cout << (char*)tempName << std::endl;
    if (FAILED(StringCchCopy(*className, (bufSize+1)*sizeof(TCHAR), tempName)))
    {
        allOk = false;
    }
    delete[] tempName;
    return allOk;
}

(最初我只是_stprintf_s使用className而不是tempName,这已被分解以查找错误所在的位置。)

上面的代码在 VC2010 Express 中编译,但*className在尝试执行该StringCchCopy行时给出了一个未处理的异常:“访问冲突写入”到(大概)。

我可以这样做

className = new TCHAR[bufSize];

在调用函数之前(后面有一个匹配 delete[]),但每次我想调用函数时我真的需要这样做吗?

我知道问题出在哪里,但不知道为什么会阻碍我想出一个可行的解决方案。在我看来,问题是我不能在 LPTSTR(通过_stprintf_sStringCchCopy)中放入一些东西,除非我使用new TCHAR[bufSize]. 我尝试为它分配一个大小完全相同但结果相同的初始值,这让我认为内存分配实际上与它无关。然后以某种方式将我的 LPTSTR 转换为 TCHAR []?我不知道这怎么可能,但在这个阶段,我什么都相信。

有人可以解释我做错了什么吗?(或者至少我的理解是错误的。)一个可能相关的问题是为什么我std::cout只显示字符串的第一个字符?

4

2 回答 2

1
wstring winClassName( int const winType )
{
    return wstring( L"Win" ) + g_WinNames[winType] + L"Class";
}

但我完全困惑为什么你有这样的全局名称数组等:这可能是一个设计级别的错误。

于 2013-02-10T13:01:46.407 回答
0

每次我想调用该函数时,我真的需要这样做吗?

LPTSTR 值不是字符串对象,它只是一个指向 TCHAR 的指针。如果不分配缓冲区,你认为字符会去哪里?您必须确保className指针参数指向您可以写入的内存缓冲区。是否每次都分配一个新的缓冲区取决于您。

正如 Alf 暗示的那样,更好的选择是完全避免直接使用指针和动态分配的数组,并返回一个字符串对象。

为什么我的 std::cout 只显示字符串的第一个字符?

如果定义了 UNICODE,请改用 std::wcout。

于 2013-02-10T13:11:51.130 回答