在 C++ 中返回 wchar_t

Returning a wchar_t in C++

我正在创建一个 return 指向 wchar_t 的函数,但每次我使用它时 return 什么都没有。

函数:

wchar_t *Character::getCharHealth() {
    wchar_t charHealth[256];
    swprintf_s(charHealth, L"%d", this->getHealth());
    wprintf(L"%s\n", charHealth);
    wchar_t* cHealth = charHealth;
    return cHealth;
}

getHealth() 函数:

int Character::getHealth() {
    return this->health;
}

使用地点:

spriteFont->DrawString(spriteBatch.get(), warrior->getCharHealth(), DirectX::SimpleMath::Vector2(40, 0));

我的代码有问题吗?

cHealth 是指向 charHealth 的指针,它是 getCharHealth 函数的局部指针。一旦函数returns,charHealth使用的内存被释放,所以cHealth是一个野指针。一种可能的解决方案是在堆上使用 newcharHealth 分配 space。

问题是您正在尝试 return wchar_t charHealth[256];

然而,这是一个局部变量,在函数结束时被销毁。虽然你可以获取它的地址,但一旦你退出该函数就没有任何意义,所以这就是你不能使用 return.

的原因

如果你想return一个你在函数中创建的数组,你需要用new显式分配它: wchar_t *charHealth = new wchar_t[256];

您正在 return 指向一个已经超出范围的数组的指针,也就是说,wchar_t charHealth[256] 一旦完成就属于 getCharHealth() 运行 这是未定义的行为再次访问 charHealth 数组。

您可以尝试为 charHealth 和 return 分配一个动态缓冲区,而不是:

wchar_t *Character::getCharHealth() {
    wchar_t* charHealth = new wchar_t[256];
    swprintf_s(charHealth, L"%d", this->getHealth());
    wprintf(L"%s\n", charHealth);
    return charHealth;
}

然后您必须记得在不再需要时delete[]它:

wchar_t* cHealth = warrior->getCharHealth();
spriteFont->DrawString(spriteBatch.get(), cHealth, DirectX::SimpleMath::Vector2(40, 0));
delete[] cHealth;

这很容易出错,您可能会忘记 delete[]。相反,如果您不熟悉,可以使用 std::unique_ptr<wchar_t[]> which automatically deletes the pointer on destruction. That's a technique called RAII

但实际上,您可能应该使用 std::wstring with std::to_wstring to convert the number from int to std::wstring,因为这样的对象包含适当的字符串存储优化并负责可能需要的任何分配。

std::wstring Character::getCharHealth() {
    std::wstring charHealth = std::to_wstring(this->getHealth());
    wprintf(L"%s\n", charHealth.c_str());
    return charHealth;
}

要从 std::wstring you should use the .c_str() 方法访问原始 const wchar_t*,如下所示:

spriteFont->DrawString(spriteBatch.get(), warrior->getCharHealth().c_str(), DirectX::SimpleMath::Vector2(40, 0));

这是由 return 堆栈上的本地分配数组引起的。在你的函数 Character::getCharHealth return 之后,内存 space 将被你的程序覆盖。

您的 gccclang 编译器应该为此输出警告消息,仔细检查这些消息可以节省您的大部分时间。

对于clang,警告由flag -Wreturn-stack-address控制,默认开启。对于 gcc,警告由标志 ​​-Wreturn-local-addr 控制,该标志也默认打开。