【问题标题】:Asisgn LPCWSTR array from std::wstring从 std::wstring 分配 LPCWSTR 数组
【发布时间】:2015-07-09 22:07:04
【问题描述】:

我正在创建一个动态的 LPCWSTR 数组,并希望在运行时分配值。 我有以下代码:

cin>>count
LPCWSTR * lpwcstrArray = new LPCWSTR[count]();

for (int i = 0; i < count; i++)
{
    // some logic to create different wstring on each iteration
    wstring tempWString = L"somerandomstuff";

    lpwcstrArray[i] = reinterpret_cast<LPSWSTR>tempWString.c_str();
}

现在,如果我访问 lpwcstrArray - 所有索引都指向分配的最后一个字符串的数据。

我知道这不是正确的赋值方式,但我不知道正确的方式。

【问题讨论】:

    标签: c++ arrays std wstring lpcwstr


    【解决方案1】:

    wstring tempWString 在循环的每次迭代中创建和销毁。
    您的 lpwcstrArray 中有悬空指针,当您访问其中一个指针时遇到了未定义的行为。
    您需要自己分配空间或使用std::wstring 作为数组类型而不是LPCWSTR

    【讨论】:

    • 感谢您的解释,因为我必须使用 LPCWSTR* ,这里分配内存的正确 api 是什么,我是 c++ 新手
    • 您将使用new。你可以google一下,别忘了你必须释放你使用delete分配的资源。
    • 谢谢,创建了一个数组来存储 wstring 然后分配,以便指针指向有效内存。
    • 接受雷米的回答,因为它提供了解决方案。不幸的是,我们不能接受超过 1 个。
    【解决方案2】:

    您正在存储指向 临时 std::wstring 对象内部的指针。当这些对象在每次循环迭代中被销毁时,您的数组就会留下危险的指针。您需要改为动态分配各个字符串,例如:

    std::cin >> count
    LPWSTR *lpwstrArray = new LPWSTR[count];
    
    for (int i = 0; i < count; i++)
    {
        // some logic to create different wstring on each iteration
        std::wstring tempWString = L"somerandomstuff";
    
        LPWSTR str = new WCHAR[tempWString.length()+1];
        const wchar_t *p = tempWString.c_str();
        std::copy(p, p+tempWString.length(), str);
    
        lpwstrArray[i] = str;
    }
    
    // use lpwstrArray as needed...
    
    // don't forget to free the memory when you are done using it...
    for (int i = 0; i < count; i++)
        delete[] lpwstrArray[i];
    delete[] lpwstrArray;
    

    根据您真正想要完成的任务,至少如果您只需要对字符串进行只读访问(您可能会这样做,如 LPCWSTR 中的 C代表const,因此数组的用户不会修改它们):

    std::cin >> count
    
    std::vector<std::wstring> wstrArray(count);
    for (int i = 0; i < count; i++)
    {
        // some logic to create different wstring on each iteration
        wstrArray[i] = L"somerandomstuff";
    }
    
    std::vector<LPWSTR> lpwstrArray(count);
    for (int i = 0; i < count; i++)
        lpwstrArray[i] = const_cast<wchar_t*>(wstrArray[i].c_str());
    
    // use lpwstrArray as needed. if you need to pass it where an
    // LPWSTR* is expected, you can use &lpwstrArray[0] for that...
    
    // lpwstrArray and wstrArray will be freed automatically
    // when they go out of scope...
    

    【讨论】:

    • 谢谢,我昨天做了第二部分,它正在工作。感谢您的回答。
    • 使用第一个循环完成此操作,创建 std::wstring 并将其分配给 LPCWSTR。
    【解决方案3】:

    试试方法

        std::wstring ws(_T("Hello"));
        LPCTSTR lps= (LPCTSTR)(ws.c_str());
    
        TRACE(lps);
    

    注意事项:

    • 您不应直接使用 W 类型(例如:LPCWSTR)。请改用 T 类型(例如:LPCTSTR)。为什么?因为它们会自动转换为应有的版本(LPCSTR 用于非 Unicode / ASCII;LPCWSTR 用于 Unicode),具体取决于您的项目。

    • 出于同样的原因,您应该使用_T() 将字符串括起来或在它们前面加上L

    • 尝试从 LPCTSTR 开始依次使用“转到定义”进行深入研究

    • 另见 _tcscpy_s 函数文档

    【讨论】:

    • 你的建议是倒退的。您应该避免使用基于 TCHAR 的 API,而改用 Unicode API。 Windows 基于 Unicode 已有近 2 年的历史了。 TCHAR API 用于为必须支持 Windows 9x/ME 的应用提供传统支持。此外,_T()(和TEXT())与L"..." 不同。
    • @RemyLebeau 我手头有 tchar.h 文件。我看到#define _T(x) __T(x) 和#define __T(x) L ## x 请解释一下在实际效果方面有什么不同。试图去 L 的定义总是把我带到别处,而不是这个 L 的定义。
    • L 没有定义,它作为 C/C++ 语言的一部分内置于编译器本身。 _T()L 仅在定义 _UNICODE 时“做完全相同的事情”,其中 _T("x") 映射到 L"x"。当 _UNICODE 未定义时,_T("x") 映射到 "x"。将 L"x" 直接传递给基于 _TCHAR 的 API 是错误的,您必须改为传递 _T("x"),这样它才能在两种环境中正确映射。当您必须为 Windows 的 Ansi (Win9x/ME) 和 Unicode (NT4+) 版本交叉编译单个代码库时,这就是您所需要的......
    • ... 不过,如今真正需要这样做的情况非常少见。尤其是在编写新代码时。现在一切都是 Unicode,每当您调用旧的基于 Ansi 的 API 时都会对性能造成影响,因此应尽可能/可行地避免使用它们(以及 TCHAR 本身)。
    • @RemyLebeau:根据您的观察,我删除了“两个选项都做同样的事情”声明。
    猜你喜欢
    • 2013-03-22
    • 2011-08-02
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多