string :: c_str查询

时间:2010-10-22 04:19:01

标签: c++ string

调用string :: c_str()返回的指针指向哪里?在下面的代码片段中,我想我会给出一个分段错误,但它给了我正确的输出。如果string :: c_str()返回的指针指向字符串对象内部的内部位置,那么当函数返回并调用对象析构函数时,我应该获得无效的内存访问。

#include <iostream>
#include <string>
using namespace std;

const char* func()
{
    string str("test");
    return str.c_str();
}

int main()
{
    const char* p = func();
    cout << p << endl;
    return 0;
}

Output: test
Compiler: g++ 4.3.3
Platform: ubuntu 2.6.28-19

2 个答案:

答案 0 :(得分:13)

  

通过调用string::c_str()返回的指针指向哪里?

它指向内存中某个包含std::string内容的以空字符结尾的字符串的位置。

指针仅在std::string被修改或销毁之前有效。如果您再次致电c_str()data(),也可能会失效。

基本上,您最安全的选择是假设下次对c_str()对象执行操作时,从std::string获取的指针无效。

  

我应该获得无效的内存访问权。

不,你得到未定义的行为。您可能会遇到某种类型的内存访问错误(如分段错误),但您的程序似乎也可能继续正常运行。它可能看起来有一次运行你的程序,但下一次失败。

答案 1 :(得分:2)

您希望打印出来的内容是什么?

#include <iostream>
#include <string>

int main()
{
  int* test = new int[20];
  test[15] = 5;
  std::cout << test[15] << "\n";
  delete[] test;
  std::cout << test[15] << "\n";
  return 0;
}

在VS 2010的发布模式中,我得到了这个结果:

  

5   
5

当您尝试访问时,释放的内存不一定会引发异常。该值也不一定会被重写。 (有趣的是,如果我将编译更改为调试模式,编译器将使用-572662307覆盖该值。

标准未定义尝试访问它时会发生什么。这意味着编译器可以做任何感觉,或者选择什么都不做。 (或者破坏你的程序,或炸毁宇宙...)