基本的c风格字符串内存分配

The*_*eOx 4 c++ memory c-strings

我正在使用现有代码开发一个项目,该代码主要使用C++但使用c风格的字符串.请考虑以下事项:

#include <iostream>
int main(int argc, char *argv[])
{
    char* myString = "this is a test";
    myString = "this is a very very very very very very very very very very very long string";
    cout << myString << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这编译并运行良好,输出为长字符串.

但是我不明白为什么它有效.我的理解是

char* myString 
Run Code Online (Sandbox Code Playgroud)

是指向一个足够大的内存区域的指针,用于保存字符串文字"这是一个测试".如果是这种情况,那我怎么能在同一个位置存储更长的字符串呢?由于尝试将长字符串塞入为较短的字符串留出的空间中,因此我预计它会在执行此操作时崩溃.

显然,对这里发生的事情有一个基本的误解,所以我感谢任何理解这一点的帮助.

Set*_*gie 14

您没有更改内存的内容,而是将指针的值更改为指向不同的内存区域"this is a very very very very very very very very very very very long string".

请注意,char* myString只为指针分配足够的字节(通常为4或8个字节).当你这样做时char* myString = "this is a test";,实际发生的事情是在程序开始之前,编译器在可执行映像中分配空间并放入"this is a test"该内存.然后,当你做char* myString = "this is a test";它实际做的事情时,只需为指针分配足够的字节,并使指针指向它在编译时已在可执行文件中分配的内存.

所以如果你喜欢图表:

char* myString = "this is a test";

(allocate memory for myString)

              ---> "this is a test"
            / 
myString---

                   "this is a very very very very very very very very very very very long string"
Run Code Online (Sandbox Code Playgroud)

然后

myString = "this is a very very very very very very very very very very very long string";

                   "this is a test"

myString---
            \
              ---> "this is a very very very very very very very very very very very long string"
Run Code Online (Sandbox Code Playgroud)

  • 啊! 那讲得通.那么当发生这种情况时,分配给原始"这是一个测试"字符串的内存是否会自动释放? (2认同)
  • @DTJon不,它仍然存在于可执行文件中,并且在整个程序中都不会发生变化.这就是为什么你永远不能做`char*a ="something"; a [1] ='f';`因为`a`指向某个_read-only_内存,并且你不允许改变它的内容. (2认同)
  • 好吧,只读内存是一个impl.细节,但修改文字是UB. (2认同)

Ada*_*hon 5

内存中有两个字符串.首先是"this is a test"让我们说它从地址0x1000开始.第二个是"this is a very very ... test"它,它从地址0x1200开始.

通过

char* myString = "this is a test";
Run Code Online (Sandbox Code Playgroud)

你创建一个被调用的变量myString并为其分配地址0x1000.然后,通过

myString = "this is a very very ... test";
Run Code Online (Sandbox Code Playgroud)

你分配0x1200.通过

cout << myString << endl;
Run Code Online (Sandbox Code Playgroud)

你只需要打印从0x1200开始的字符串.