2

在 VC++ 中,当我对 to 返回的值进行类型转换并const char*打印转换后的值时,屏幕上不会打印任何内容。这是代码片段std::string::c_str()char*

#include "stdafx.h"
#include <string>

using namespace std;

string test() { return(string("HELLO"));}


int _tmain(int argc, _TCHAR* argv[])
{
  char* val;
  val = (char*) test().c_str();
  printf("\n %s\n", val);
  return 0;
}

当我简单地检查 ASCII 值时,val[0]它是 0。但是在 G++ 下,文本HELLO会显示出来。

从 const char* 到 char* 的强制转换是非标准的,其结果未定义吗?

4

3 回答 3

7

只要您在更改字符串后不修改值或从中读取值,强制转换就可以了(尽管您至少应该得到一个警告)。

问题是您在临时上调用该函数(临时是由string返回的cat())。在 之后;,临时对象超出范围,val仍然指向由临时对象管理的内存。它是 UB 从中读取的。

于 2012-08-30T21:11:17.710 回答
3

你得到未定义的行为,因为临时返回的test()立即被销毁。演员与它无关。

要消除此问题,请将返回的值分配给test()局部变量。现在它将通过对 的调用继续存在printf

int _tmain(int argc, _TCHAR* argv[])
{
  string temp;
  char* val;
  temp = test();
  val = (char*) temp.c_str();
  printf("\n %s\n", val);
  return 0;
}
于 2012-08-30T21:10:56.053 回答
0

请注意,如果没有演员表,您会得到类似的行为(将类型更改valchar const*):

char const* val;
val =  test().c_str();
printf("\n %s\n", val);

正如其他答案中提到的,这个特定示例中的问题不是强制转换,而是由返回的指针指向的数据的生命周期c_str()。当从它获取的对象死亡时,该数据无效(在这种情况下,它位于行尾的分号,因为它是test()函数返回的临时对象)。

请注意,正如克里斯在评论中指出的那样,即使指针是从c_str()对寿命较长的对象的调用中获得的,数据也可能由于其他原因变得无效(基本上是在字符串对象被修改的情况下)。

于 2012-08-30T21:23:53.540 回答