高级C内存分配

时间:2013-03-22 17:20:02

标签: c

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

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

6 个答案:

答案 0 :(得分:4)

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

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

类似

答案 1 :(得分:4)

如果在函数中放置定义char *str;,那么它是“指向 - char”类型的自动变量。

它位于堆栈中,当函数返回时,堆栈的那一部分变为未使用(编译器通过发出代码来根据需要移动堆栈指针来处理此问题)。从理论上讲,堆栈的存在纯粹是一个实现细节,实际上C总是有一个调用堆栈,几乎所有的实现都或多或少地以相同的方式管理,然而它实际上是被管理的,存储自动变量的内存是可能被称为“堆栈”。

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

它存储在读写数据段中,并在程序退出时变为未使用(可能是OS为您处理此问题,尽管它原则上可能是编译器发出的代码)。由于它是零初始化的(假设一个架构,其中空指针由所有位零表示)是,它可以进入bss段,这专门用于具有静态存储持续时间的零初始化读写对象。同样,存储静态持续时间对象的详细信息取决于实现,但同样,这也是通常的完成方式。

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

答案 2 :(得分: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”将被放置(希望)在只读内存区域。

答案 3 :(得分:2)

我认为你已经混淆了指针以及它们指向的内容。拿这个:

char *str = "Hello";

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

如果它在函数中声明,那么str是在堆栈上分配的指针。文字是独立的。

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

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

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

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

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

答案 4 :(得分:1)

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

Memory Layout of C ProgramsStorage for Strings in C

答案 5 :(得分: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 Segment)都需要在程序本身中释放。因此,如果您使用malloc,calloc或任何在运行时分配内存的函数,则需要使用free()。