3

我有这个简单的功能:

const wchar_t *StringManager::GetWCharTStar(int stringId)
{
    std::wstring originalString = StringManager::GetString(stringId);
    const wchar_t *retStr = originalString.c_str();
    return retStr;
}

在该函数的第二行,我有正确的 wchar_t*。但是,当我返回时,数据会切换为垃圾数据。中间没有函数。是什么赋予了?!

4

5 回答 5

11

originalString 在堆栈上分配。.c_str() 方法只返回一个指向 wstring 对象的一些连续内部存储器的指针。当函数返回时, originalString 超出范围并被销毁,因此您返回的指针值指向已删除的内存。

如果您需要这样做,您应该将数据复制到您使用 new 或 malloc() 分配的内存中,然后调用者必须删除/释放()该内存。

于 2009-12-07T17:38:51.703 回答
5

您正在返回一个指向临时的指针。当 originalString 超出范围时,您的指针指向的数据将被删除。

于 2009-12-07T17:38:56.330 回答
3

std::wstring originalString;是函数体内的局部变量GetWCharTStar

一旦你离开GetWCharTStar()函数的作用域,这个局部变量就会被破坏,你返回的指针不再有效。

以下代码最终可能会起作用:

const wchar_t *StringManager::GetWCharTStar(int stringId)
{
    const std::wstring& originalString = StringManager::GetString(stringId);
    const wchar_t *retStr = originalString.c_str();
    return retStr;
}

提供StringManager::GetString()返回参考:

const std::wstring& StringManager::GetString(int stringId);

但是,这仍然是有风险的,因为它假定您的StringManager类管理的字符串永远不会在内存中重新定位。例如,如果StringManager在一个 then 的帮助下实现,std::vector一旦向量需要扩展,它之前的内容就会被复制到更大的内存块中的其他地方,最终你会持有一个不再存在的对象的引用。

换句话说,避免将句柄返回到内部数据

于 2009-12-07T17:39:43.817 回答
1

前面的答案大多是正确的,除了一个小细节。您没有返回指向已销毁对象的指针,而是返回了已销毁对象拥有的指针。当该对象被销毁时,您的指针指向的对象也被销毁。

于 2009-12-07T17:42:56.197 回答
0

这是一个常见问题解答。在您实际使用它之前,您正在返回一个指向已释放对象(originalString 对象)的指针。

于 2009-12-07T17:39:23.987 回答