2013-03-22 71 views
1

因此,我继续了解C,并且我有一个有趣的问题。 如果我没有把错误的东西放在堆上,我必须使用malloc等。 但char * str呢? 在什么内存段将str位于? 我读过它会放在.bss段(这就是为什么你不能在C中改变字符串)。它是否正确?或者将它放在堆栈上?高级C内存分配

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

+0

也许这可能会帮助http://stackoverflow.com/questions/14004302/how-c-strings-are-allocated-in-memory?rq=1 – 2013-03-22 17:24:04

+1

声明'char * str;'只分配一个空间指针对象。如果你想指向一个数组(可能包含也可能不包含字符串),那么必须通过调用'malloc()',通过使用字符串文字,通过定义数组对象或其他东西。 – 2013-03-22 17:25:46

+0

嗨。我的问题是这个内存在哪里?在堆栈或BSS段? – Farseer 2013-03-22 17:29:03

回答

4

如果你把一个定义char *str;放在一个函数中,那么它是一个类型为“pointer-to-char”的自动变量。

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

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

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

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

4

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

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

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

2

我认为你已经混淆了指针和它们指向的内容。借此:如果多数民众赞成在文件范围内声明的

char *str = "Hello"; 

,然后str是静态分配的指针。它指向的字符串是完全独立的。你可以有str指向任何东西。

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

事实上,如果你有以下两行:

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

的编译器就可以让每个指向内存中的同一地址。

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

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

0

在C中,我们可以通过字符数组或字符指针指任一字符串。

情况1:如果字符串被称为字符数组:

char[] = "storage of strings"; 

如果上述声明是GLOBAL那么这被存储在数据段否则这将被存储在堆栈段。

案例2:如果字符串被字符指针引用,并且在运行时分配内存(即使用malloc,calloc)。

char *str = (char *)malloc(sizeof(char)*size); 

在这种情况下,存储器是从HEAP段中分配的。

案例3:如果通过字符指针引用字符串并将字符串值直接赋值给字符指针。

char *str = "storage of strings" 

在这种情况下,这将被存储在DATA segment.It是像字符串文字被分配在数据段和这个字符串是分配给str变量的地址的存储器。

PS:每个在运行时分配的内存(HEAP段)都需要在程序本身中释放。所以如果你使用malloc,calloc或任何在运行时分配内存的函数,你需要使用free()。