1

所以,我继续学习 C。我有一些有趣的问题。如果我没有弄错将东西放在堆上,我必须使用mallocetc.. 但是呢char * str?将str位于哪个内存段中?我读到它将被放在 .bss 段上。(这就是为什么你不能在 C 中更改字符串)。它是否正确?或者它会被放在堆栈上吗?

如果是,为什么程序结束时不需要释放这个内存?每个函数的代码位于哪个内存段中?换句话说,指向函数的指针将指向哪个段?谢谢您的帮助!只是试图更好地理解 C 中的内存管理。

4

6 回答 6

4

如果只是说char * str不会分配数组的内存,只会分配指针本身的内存。您将需要手动为字符串分配内存,可能在堆上,也可能手动释放它。

“您不能在 C 中更改字符串”是错误的。您不能更改字符串常量,并且字符串常量分配在类似.rodata(只读部分)中。与任何其他代码一样,函数代码位于类似.text.

于 2013-03-22T17:30:53.267 回答
4

如果将定义char *str;放在函数中,那么它就是“pointer-to-”类型的自动变量char

它位于堆栈上,当函数返回时,堆栈的那一部分将变为未使用(编译器会通过发出代码以根据需要移动堆栈指针来为您处理这一点)。理论上堆栈的存在纯粹是一个实现细节,实际上C总是有一个调用堆栈,几乎所有实现都以或多或少相同的方式管理它,但实际上它是如何管理的,存储自动变量的内存是容易被称为“堆栈”。

如果您将定义char *str;放在任何函数之外,那么它就是具有静态存储持续时间的全局变量。

它存储在读写数据段中,并在程序退出时变得未使用(可能操作系统会为您处理这个,尽管它原则上可能是编译器发出的代码)。由于它是零初始化的(并假设空指针由所有位为零表示的体系结构)是的,它可以进入 bss 段,该段专门用于具有静态存储持续时间的零初始化读写对象。同样,如何存储静态持续时间的对象的细节取决于实现,但同样,这是它通常的完成方式。

这些都与不可修改的字符串文字有任何关系,因为您还没有定义字符串(更不用说使用字符串文字了)。您已经定义了一个指针,它可以指向一个字符串,但(还)没有这样做。

于 2013-03-22T17:31:26.730 回答
2

在 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”将(希望)放置在只读内存区域中。

于 2013-03-22T17:37:39.700 回答
2

我认为您混淆了指针及其指向的内容。拿着这个:

char *str = "Hello";

如果这是在文件范围内声明的,那么str是静态分配的指针。它指向的字符串是完全独立的。你可以str指向任何东西。

相反,如果它是在函数中声明的,则str在堆栈上分配一个指针。同样,文字是分开的。

事实上,如果你有这两行:

char *str1 = "Hello";
char *str2 = "Hello";

编译器可以自由地让每个指向内存中的相同地址。

无论指针如何,字符串文字都是静态分配的,并且(通常)放置在初始化的只读数据段中。

还要记住,堆、堆栈和段的所有概念都纯粹与实现相关联,而不是与语言相关联。

于 2013-03-22T17:38:31.387 回答
1

在阅读类似问题的答案时,我只找到了两个链接。这些可能会帮助您更好地理解这个问题。

C 程序的内存布局和 C字符串的存储

于 2013-03-22T18:04:13.930 回答
0

在 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()。

于 2016-01-08T07:31:07.073 回答