关于此主题有许多类似的问题,但他们没有回答以下问题:
如果你想在下一个标题中直接回答问题,我将采取行动。如果我在这里作出任何错误的假设,请纠正我。
让我们假设,我有这个字符串声明
char* cpHelloWorld = "Hello World!";
我理解编译器会将char*
存储到存储器中某处存储的匿名数组中(顺便说一下:它存储在哪里?)。
如果我有这个声明
char cHelloWorld[] = "Hello World!";
没有匿名数组,因为编译器会立即创建数组cHelloWorld
。
这两个变量之间的第一个区别是我可以更改cpHelloWorld
,而数组cHelloWorld
是只读的,如果我想更改它,我将不得不重新声明它。
cpHelloWorld = "This is a pretty long Phrase, compared to the Hello World phrase above.";
我的应用程序如何在运行时在运行时分配一个新的,更大的(匿名)数组?我应该使用这种方法与指针,因为它似乎更容易使用或有任何缺点?在纸面上,我会使用malloc,如果我必须使用动态数组。
我的猜测是,每次更改数组内容时,编译器(或运行时环境?)都会创建一个新的匿名数组。
答案 0 :(得分:3)
char* cpHelloWorld = "Hello World!";
是存储在只读内存中的 String Literal 。您无法修改此字符串的内容。
char cHelloWorld[] = "Hello World!";
是 char
的数组,已初始化为"Hello World!\0"
。
(注意:放置括号的位置)
编译器在运行时分配的内存量由初始化"This is a pretty long ... phrase above.";
设置。编译器将初始化文本,允许初始化字符串char
中每个字符为1 +1
对于所需的 nul-terminatedating 字符。
您是使用静态声明的数组(例如char my_str[ ] = "stuff";
)还是寻求为字符动态分配存储空间,这在很大程度上取决于您是否知道要存储的内容的数量和数量。显然,如果您事先知道字符串是什么,使用字符串文字或类型为char 的初始化数组是一种简单的方法。
然而,当你不知道将要存储什么或者多少时,然后声明指向char 的指针(例如char *my_string;
然后一旦你有数据存储,你可以为my_string
分配存储空间(例如my_string = malloc (len * sizeof *my_string);
(当然sizeof *my_string
对于字符数组将是1
,因此可以省略)(注意:sizeof (explicit type)需要>括号,例如sizeof (int)
,但与变量一起使用时是可选的)
然后只需free
在不再需要值时分配的任何内容。
答案 1 :(得分:0)
事实上,编译时编译器已知的所有字符串都在程序的数据段中分配。指针本身位于堆栈上。
在运行时没有内存分配,所以它与malloc完全不同。这里没有性能缺陷。
答案 2 :(得分:0)
在这些上下文中使用的每个常量“匿名”字符串都存在于其固定地址。唯一的动态部分是实际的指针赋值。每次从特定的匿名字符串执行特定的指针赋值时,您应该获得相同的字符串地址(每个字符串都有自己的地址)。