带有文本的 char* 是否会像使用 malloc 一样自动保留内存?

Does char* with text automatically reserves memory as if malloc is used?

// Example program
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char **p;
    p = (char **)malloc(100);
    p[0] = (char *)"Apple";      // or write *p, points to location of 'A'
    p[1] = (char *)"Banana";     // or write *(p+1), points to location of 'B'

    cout << *p << endl;          //Prints the first pointer 
}

在上面的代码中:

p[0] = (char *)"Apple"; 

似乎自动预留内存。没有 malloc。这是 C/C++ 标准还是特定于编译器?

更新 1 我实际上对它在 C 和 C++ 中的表现很感兴趣。只是我没有为上面的代码安装C编译器,所以我使用了C++。

那么p是在指向HEAP中的一块内存(数组)的STACK上分配的,其中每个元素都指向(是一个指针)DATA段中的文字?哇!

malloc 动态 内存分配。这里有经典的 static 内存分配,其中字符串常量将分配到二进制文件的数据部分(如果我没记错的话)。编译器预先知道你需要多少字节,所以它只会在编译期间分配它。这与 malloc 相反,您可以在 malloc 中请求在运行时计算的任意数量的字节,并且事先未知。

与声明为常量长度的数组相同,但不使用 malloc

[这是 C 答案,因为该问题最初也被标记为 [c]。但它也主要适用于 C++。]

当你说

char *str = "text"

或者,如您的代码所示,

p[0] = "Apple";

编译器 确实 为这些字符串 "test""Apple" 分配内存。然而,这绝对不像 malloc 被调用。特别是,存储这些字符串的内存不能保证(而且,现在,通常是不可写的)。而且您不能将这些指针传递给 freerealloc——因为,同样,它们首先不是来自 malloc

这是 C(以及,推而广之,C++)的一个长期存在的方面,永远适用于任何编译器。

seems to reserve memory automatically. There is no malloc.

动态分配不是在 C++ 中获取内存的唯一方法。

变量p有自动存储。字符串文字是具有静态存储的数组。 Objects 自动销毁静态或线程本地存储。所有变量都具有这三个存储持续时间之一。

自动objects在(最窄的周围)范围结束时销毁,静态objects在mainreturns和线程本地[=63=之后销毁] 在线程退出时被销毁。

Is this C/C++ standard or compiler specific?

示例程序大部分是标准的,除了:

  • 您没有包含保证声明 malloc 的 header。
  • 您尚未在动态分配的内存中创建 char* objects,因此从技术上讲,该程序的行为在 C++ 中未定义。参见 P.P.P.S。下面介绍如何解决这个问题。

P.S。使用指向 char 的 non-const 指针指向字符串文字是非常不安全的。尝试通过此类指针修改字面量在语法上是正确的,但程序的行为在运行时将是未定义的。请改用 const char*。方便的是,您可以去掉一些显式转换。

P.P.S。 C-style 不建议在 C++ 中进行显式转换。请改用 static_castconst_castreinterpret_cast 或其组合。

P.P.P.S。不建议在 C++ 中使用 malloc。使用 newnew[] 代替......甚至更好,请参阅下一点。

P.P.P.P.S。不建议拥有指向动态内存的裸指针。在此处使用 std::vector 等 RAII 容器是个好主意。

P.P.P.P.P.S。您的示例程序泄漏了动态分配。这是避免裸拥有指针的原因之一。


So p is allocated on the STACK pointing to a block of memory (array) in the HEAP where each element points (is a pointer) to a literal in the DATA segment?

语言本身与堆栈和堆内存以及数据段等概念无关。这些是特定于您正在使用的系统上的语言实现的详细信息。