所以,我继续学习 C。我有一些有趣的问题。如果我没有弄错将东西放在堆上,我必须使用malloc
etc.. 但是呢char * str
?将str
位于哪个内存段中?我读到它将被放在 .bss 段上。(这就是为什么你不能在 C 中更改字符串)。它是否正确?或者它会被放在堆栈上吗?
如果是,为什么程序结束时不需要释放这个内存?每个函数的代码位于哪个内存段中?换句话说,指向函数的指针将指向哪个段?谢谢您的帮助!只是试图更好地理解 C 中的内存管理。
所以,我继续学习 C。我有一些有趣的问题。如果我没有弄错将东西放在堆上,我必须使用malloc
etc.. 但是呢char * str
?将str
位于哪个内存段中?我读到它将被放在 .bss 段上。(这就是为什么你不能在 C 中更改字符串)。它是否正确?或者它会被放在堆栈上吗?
如果是,为什么程序结束时不需要释放这个内存?每个函数的代码位于哪个内存段中?换句话说,指向函数的指针将指向哪个段?谢谢您的帮助!只是试图更好地理解 C 中的内存管理。
如果只是说char * str
不会分配数组的内存,只会分配指针本身的内存。您将需要手动为字符串分配内存,可能在堆上,也可能手动释放它。
“您不能在 C 中更改字符串”是错误的。您不能更改字符串常量,并且字符串常量分配在类似.rodata
(只读部分)中。与任何其他代码一样,函数代码位于类似.text
.
如果将定义char *str;
放在函数中,那么它就是“pointer-to-”类型的自动变量char
。
它位于堆栈上,当函数返回时,堆栈的那一部分将变为未使用(编译器会通过发出代码以根据需要移动堆栈指针来为您处理这一点)。理论上堆栈的存在纯粹是一个实现细节,实际上C总是有一个调用堆栈,几乎所有实现都以或多或少相同的方式管理它,但实际上它是如何管理的,存储自动变量的内存是容易被称为“堆栈”。
如果您将定义char *str;
放在任何函数之外,那么它就是具有静态存储持续时间的全局变量。
它存储在读写数据段中,并在程序退出时变得未使用(可能操作系统会为您处理这个,尽管它原则上可能是编译器发出的代码)。由于它是零初始化的(并假设空指针由所有位为零表示的体系结构)是的,它可以进入 bss 段,该段专门用于具有静态存储持续时间的零初始化读写对象。同样,如何存储静态持续时间的对象的细节取决于实现,但同样,这是它通常的完成方式。
这些都与不可修改的字符串文字有任何关系,因为您还没有定义字符串(更不用说使用字符串文字了)。您已经定义了一个指针,它可以指向一个字符串,但(还)没有这样做。
在 C 语言中,所有局部变量都将被放入堆栈。该变量str
是一个字符指针。它包含一个内存地址。在堆栈上只会被这个指针称为str
。
char * str;
这会在堆栈上分配指针大小的内存(32/64 位上的 4 或 8 个字节)。
str = malloc(1024);
malloc
在堆上分配 1024 个字节并返回指向该内存区域第一个字节的指针。该指针保存在str
位于堆栈中的哪个位置。
当函数(其中是局部变量)返回时,您的变量str
将被释放。str
指向的内存区域str
不会自动释放。您需要使用 手动执行此操作free(str)
。
字符串可以修改!但不是常量文字:
char string[4] = "foo";
string[0] = 'F'; //will work
char * stringconst = "foo";
stringconst[0] = 'F'; // this will segfault
以上将不起作用,因为“foo”将(希望)放置在只读内存区域中。
我认为您混淆了指针及其指向的内容。拿着这个:
char *str = "Hello";
如果这是在文件范围内声明的,那么str
是静态分配的指针。它指向的字符串是完全独立的。你可以str
指向任何东西。
相反,如果它是在函数中声明的,则str
在堆栈上分配一个指针。同样,文字是分开的。
事实上,如果你有这两行:
char *str1 = "Hello";
char *str2 = "Hello";
编译器可以自由地让每个指向内存中的相同地址。
无论指针如何,字符串文字都是静态分配的,并且(通常)放置在初始化的只读数据段中。
还要记住,堆、堆栈和段的所有概念都纯粹与实现相关联,而不是与语言相关联。
在阅读类似问题的答案时,我只找到了两个链接。这些可能会帮助您更好地理解这个问题。
在 C 语言中,我们可以通过字符数组或字符指针来引用字符串。
案例1:如果字符串被称为字符数组:
char[] = "storage of strings";
如果上述声明是 GLOBAL 则存储在 DATA 段中,否则将存储在 STACK 段中。
情况 2:如果字符串由字符指针引用,并且在运行时分配内存,即使用 malloc、calloc。
char *str = (char *)malloc(sizeof(char)*size);
在这种情况下,内存是从 HEAP 段分配的。
情况 3:如果字符串由字符指针引用,并且字符串值直接分配给 char 指针。
char *str = "storage of strings"
在这种情况下,这将存储在 DATA 段中。就像在数据段中为字符串文字分配了一个内存,并将该字符串文字的地址分配给 str 变量。
PS:在运行时分配的每个内存(HEAP 段)都需要在程序本身中释放。因此,如果您使用 malloc、calloc 或任何在运行时分配内存的函数,则需要使用 free()。