微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法修改 const wchar * 的向量

如何解决无法修改 const wchar * 的向量

我有一个将字符串列表转换为 const wchar_t * 向量的函数

void convertListtoVector(std::vector<const wchar_t *>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");

    std::list<std::wstring>::iterator itr;
    
    for (itr = Inserts.begin(); itr != Inserts.end(); itr++) {
        messageInserts.push_back((*itr).c_str());
    
    }
}

我是这样称呼它的:

std::vector<const wchar_t *> msg;
convertListtoVector(msg);

但是在执行函数之后,我有一个包含 3 个空字符串的向量。当我调试我的代码时,我注意到函数内部的向量正在用字符串更新,但在函数返回后,我看到大小从 0 变为 3,但所有字符串都是空的“”。我想要带字符串的向量。请让我知道我哪里出错了。 提前致谢。

解决方法

使用地址清理程序构建您的程序时,我们检测到内存错误:AddressSanitizer: heap-use-after-free

通常在现代 C++ 中,我们不建议使用原始指针:我们更喜欢使用容器。

您已经存储了为什么在函数返回后由 local std::list 拥有的字符串地址,这些地址是不可访问的(您在打印时得到一个空字符串,但实际上它可能会崩溃),我们可以修复它3 种选择:

  1. 复制
void convertListtoVector(std::vector<std::wstring>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");

    std::list<std::wstring>::iterator itr;
    
    for (itr = Inserts.begin(); itr != Inserts.end(); itr++) {
        messageInserts.push_back(*itr);
    
    }
}

或使用 STL 算法

void convertListtoVector(std::vector<std::wstring>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");
    messageInserts.insert(messageInserts.end(),Inserts.begin(),Inserts.end());
}
  1. 从本地容器移动,因为不再需要本地列表,对于大字符串,移动它们将获得性能提升
void convertListtoVector(std::vector<std::wstring>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");
    
    for (itr = Inserts.begin(); itr != Inserts.end(); itr++) {
        messageInserts.push_back(std::move(*itr));
    }
}

或使用 STL 算法

void convertListtoVector(std::vector<std::wstring>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");
    messageInserts.insert(messageInserts.end(),std::make_move_iterator(Inserts.begin()),std::make_move_iterator(Inserts.end()));
}
  1. 使本地 list 成为静态,但这可能容易出错:
void convertListtoVector(std::vector<const wchar_t*>& messageInserts)
{
    static std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");

    std::list<std::wstring>::iterator itr; 
    for (itr = Inserts.begin(); itr != Inserts.end(); itr++) {
        messageInserts.push_back(itr->c_str());
    }
}
,

您的向量存储一个指向字符串的指针,该字符串的生命周期由 std::list 管理。当列表作为局部变量被删除时,所有托管字符串也被删除,并且向量中留下悬空指针。

您必须对列表的字符串内容进行深拷贝:

void convertListtoVector(std::vector<const wchar_t *>& messageInserts)
{
    std::list<std::wstring> Inserts;
    Inserts.push_back(L"str1");
    Inserts.push_back(L"str2");
    Inserts.push_back(L"str3");

    std::list<std::wstring>::iterator itr;
    
    for (itr = Inserts.begin(); itr != Inserts.end(); itr++) {
        wchar_t *cloneStr = new wchar_t[wcslen(itr->c_str())+1];
        wcscpy(cloneStr,itr->c_str());
        messageInserts.push_back(cloneStr);
    }
}

int main(){
    std::vector<const wchar_t *> msg;
    convertListtoVector(msg);
    for (const wchar_t* str : msg) {
        std::wcout << str << std::endl;
        delete[] str;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。