【问题标题】:Returning Char Pointer Without Heap返回没有堆的字符指针
【发布时间】:2015-04-20 05:46:21
【问题描述】:

我正在开发一个程序,我注意到一些对我来说并没有太大意义的东西。 std::string 有一个名为 c_str() 的函数,它返回 std::string 对象的 C 样式字符串(以 NULL 结尾)表示。对我来说没有意义的是 c_str() 函数如何返回 const char * 而无需将其分配给堆。该函数看似返回堆栈上的 char 数组。

我一直认为,如果函数指向的值是使用malloc()calloc() 之类的函数在堆上分配的,则函数只能返回有效指针。

c_str() 如何在不使用堆的情况下返回字符串,我能否在自己的代码中以某种方式模仿同样的行为?

提前谢谢大家。

【问题讨论】:

标签: c++ pointers std cstring stdstring


【解决方案1】:

下面是一个函数的例子,它返回一个指向不是堆或堆栈的指针:

char const * Hello(void)
{
  static const char hello_text[] = "Hello";
  return &hello_text[0];
}

因为变量被声明为static,所以在执行离开函数后变量会存在。因此,返回一个指向该值的指针是完全有效的。

【讨论】:

    【解决方案2】:

    c_str()返回的指针实际上是一个指向字符串缓冲区内存的内部指针(已经在堆上分配了)。这样就不必分配任何(新)内存。内存已经分配,​​是字符串对象存储数据的方式。

    这就是为什么c_str()返回的指针是invalid after modifying the string的原因:因为它指向一个内部缓冲区,这个缓冲区在操作后可能不再有效。

    从 c_str() 中获得的指针可能会通过以下方式失效:

    • 将对字符串的非常量引用传递给任何标准库函数,或者
    • 在字符串上调用非常量成员函数,不包括 operator[]、at()、front()、back()、begin()、rbegin()、end() 和 rend()。

    请注意,由于 C++11,c_str()data() 执行相同的功能,并且其工作方式类似于 std::vectordata() 成员的工作方式。

    【讨论】:

    • 感谢您的回答和额外信息。这澄清了我的很多困惑。
    • (which has already been allocated on the heap) 可能不是,取决于std::string是否使用短字符串优化。
    【解决方案3】:

    指针可以指向任何变量,无论是在堆上还是栈上。 c_str 返回一个指向字符串对象内部缓冲区的指针。通常这是在堆上,但是一些编译器可以自行决定将小字符串的数据放在堆栈上。但是,您怎么知道返回的指针是在堆栈上而不是在堆上?

    我不确定你到底想在自己的代码中模仿什么。

    【讨论】:

    • 好吧,我不知道它是真正在堆栈上还是在堆上,但是,我假设堆栈是因为您不需要释放返回的变量。也就是说,谢谢你的信息。我将不得不阅读内部缓冲区。我希望模仿的是返回指向对象的指针,而不必对其进行 malloc 或将它们声明为 new
    • 字符串对象news内部数据,当字符串对象自动超出范围时,其析构函数将delete数据。 c_str 不会返回“新”数据,而只是让您查看已经存在的数据。
    • 哦,好吧,这更有意义。那么,为了简化,这会类似于垃圾收集器系统吗? (当然,仅限于内部缓冲区。)
    • 是的,在某种程度上。现代 C++ 通过使用标准容器和智能指针减少了手动内存管理的需要,例如 newmalloc。这会产生更安全的代码,不会泄漏内存。
    • 非常感谢,很高兴知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2011-01-21
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多