在C ++中返回wchar_t

时间:2015-05-12 03:24:55

标签: c++ wchar-t

我正在创建一个返回指向wchar_t的指针的函数,但每次使用它时都不会返回任何内容。

功能:

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));

我的代码有什么问题吗?

4 个答案:

答案 0 :(得分:2)

cHealth是指向charHealth的指针,getCharHealthcharHealth函数的本地指针。函数返回后,cHealth使用的内存将被释放,因此charHealth是一个野指针。一种可能的解决方案是使用new在堆上为class Program { static void Main(String[] args) { Console.WriteLine(RoundAndFormat(1)); Console.WriteLine(RoundAndFormat(10)); Console.WriteLine(RoundAndFormat(100)); Console.WriteLine(RoundAndFormat(1000)); Console.WriteLine(RoundAndFormat(100000)); Console.WriteLine(RoundAndFormat(125000)); Console.WriteLine(RoundAndFormat(125900)); Console.WriteLine(RoundAndFormat(1000000)); Console.WriteLine(RoundAndFormat(1250000)); Console.WriteLine(RoundAndFormat(1258000)); Console.WriteLine(RoundAndFormat(10000000)); Console.WriteLine(RoundAndFormat(10500000)); Console.WriteLine(RoundAndFormat(100000000)); Console.WriteLine(RoundAndFormat(100100000)); Console.ReadLine(); } public static String RoundAndFormat(Int32 value) { var result = String.Empty; var negative = value < 0; if (negative) value = value * -1; if (value < 1000) { result = value.ToString(); } else if (value < 1000000) { result = RoundDown(value / 1000.0, 0) + "K"; } else if (value < 100000000) { result = RoundDown(value / 1000000.0, 2) + "M"; } else if (value < 10000000000) { result = RoundDown(value / 1000000.0, 0) + "M"; } if (negative) return "-" + result; return result; } public static Double RoundDown(Double value, Int32 digits) { var pow = Math.Pow(10, digits); return Math.Truncate(value * pow) / pow; } 分配空间。

答案 1 :(得分:1)

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

但是,这是一个局部变量,在函数结束时被销毁。虽然您可以使用其地址,但一旦退出该功能就没有任何意义,这就是您无法使用该返回的原因。

如果要返回在函数中创建的数组,则需要使用new明确分配它: wchar_t *charHealth = new wchar_t[256];

答案 2 :(得分:1)

您正在返回指向已超出范围的数组的指针,wchar_t charHealth[256]一旦完成运行就属于getCharHealth()&#39 ; s未定义的行为,以再次访问charHealth数组。

您可以尝试为charHealth分配动态缓冲区,然后返回:

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[]>自动删除销毁时的指针。如果您不熟悉,这是一种名为RAII的技术。

但实际上,您可能应该使用std::wstringstd::to_wstring将数字从int转换为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访问原始const wchar_t*,您应该使用.c_str()方法,如下所示:

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

答案 3 :(得分:0)

这是由返回堆栈上的本地分配数组引起的。函数Character::getCharHealth返回后,程序将覆盖内存空间。

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

对于clang,警告由标记-Wreturn-stack-address控制,默认情况下已打开。对于gcc,警告由标记-Wreturn-local-addr控制,默认情况下也会打开。