【问题标题】:Return a string but get garbage [duplicate]返回一个字符串但得到垃圾[重复]
【发布时间】:2016-09-29 16:16:52
【问题描述】:

我正在尝试从这样的函数返回一个字符串:

virtual const char* what() const throw()
{   
    std::string str = "Name Error: name ";
    str+= n_name;
    str += " is not defined";
    char ret[256]="";
    const char* temp = str.c_str();
    strcpy(ret, temp);
    return ret;
}

但是当我尝试在另一个地方打印它时:

const char* str= exc.what();
std::cout << str;

输出是垃圾。

我以为问题是char[],应该是char*,但是当我把它改成

char* ret="";

程序崩溃了

strcpy(ret, temp);

有人可以帮帮我吗? 附:该函数必须返回一个 const char*

【问题讨论】:

  • 你返回一个指向无效内存的指针。您需要分配一些您的指针将指向的内存。参见“malloc”或“new[]”。

标签: c++ string char return strcpy


【解决方案1】:

当what() 返回并将返回值存储到str 时,数组ret 将因其作用域而被销毁,而从what() 返回的指针是一个悬空指针,会导致未定义的行为在解除防御时。您应该new 数组(以及使用它后的delete)或者只返回一个std::string。

【讨论】:

  • 谢谢我找到了办法!
【解决方案2】:

您似乎正在尝试实现异常。你为什么不直接从std::runtime_error 继承,它已经提供了实现这项工作的机制?你只需要将你想要的消息传递给它的构造函数。

见http://en.cppreference.com/w/cpp/error/runtime_error

【讨论】:

  • 这是任务的一部分——创建异常。还是谢谢
  • 如果您询问真正的问题,您可能会得到更好的答案。但我认为您可能会发现这很有用:stackoverflow.com/a/134612/212870
【解决方案3】:

主要问题来自返回指向局部变量的指针。如果您使用-Wall 编译器选项(我鼓励您在完成的每个编译中使用),您将获得:

警告:返回的局部变量 'ret' 的地址 [-Wreturn-local-addr]

确实,char ret[256]=""; 是本地函数。在函数结束时,局部变量不再存在。所以,当std::cout &lt;&lt; str;被执行时,指向的内存就不再存在了。

当您使用char* ret=""; 时,您不会分配内存。您只有一个指向包含"" 的只读静态内存的指针。并且始终使用-Wall 选项,您会收到一条警告,提示您做错了什么:

警告:ISO C++ 禁止将字符串常量转换为 'char*' [-Wwrite-strings]

你必须分配内存:

char * ret = new char[str.size()+1];

但请注意,每个 new 都必须有一个 delete => 每个手动分配的内存都应该手动释放

【讨论】:

  • 你确定 char ret[256]="" 分配内存吗?它与指向只读静态内存的 char* ret="" 有何不同?
  • char ret[256]="" 自动在堆栈上为 256 char 分配内存并将其初始化为""。释放在函数结束时自动完成
  • 非常感谢!现在可以使用了!
猜你喜欢
  • 1970-01-01
  • 2020-01-08
  • 2013-10-30
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多