一、正文段。可执行程序在存储空间的的副本,cpu执行的机器指令部分。
二、初始化的数据段。它包含明确地赋初值的变量。如: int a = 1; 此变量放于数据段。
三、未初始化的数据段。 内核将此段中的数据初始化为0或者空指针。出现在任何函数外的c声明 ,long sum[1000];此变量存放在非初始化数据段中。
四、栈。每次函数调用时,其返回地址以及调用者的环境信息都存放在栈中。最近被调用的函数在栈上为其自动和临时变量分配存储空间。每次函数调用结束后,系统会自动收回内存。(见下面的程序1说明)
五、通常在堆中进行动态存储分配。每次函数被调用结束后,系统不会收回内存。如下图所示:
我们首先说一下,栈的应用。
程序1:
#include <stdio.h>
#include <stdlib.h>
char *GetString(void)
{
char p[] = "Hello, World";
return p;
}
int main(void)
{
char *str = NULL;
str = GetString();
printf("%s\n", str);
}
上面的程序例子,是错误的。因为 char p[] = "Hello, World"; 数组占有的空间在函数GetString()调用后,将会把收回,所以是错误的。一般编译器会报出这样的错误, warning: function returns address of local variable,
因此说,千万不能用return语句返回指向“栈内存”的指针。
然后我再说一下堆的应用吧。
程序二
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *GetString(int num)
{
char *p = (char *)malloc(sizeof(char)* num);
return p;
}
int main(void)
{
char *str = NULL;
str = GetString(100);
strcpy(str, "Hello, World");
printf("%s\n", str);
free(str);
}
在程序二中,GetString()申请空间,函数被调用结束后,不会被释放。故空间可以被使用。 因此可以说,用return语句可以返回指向“堆内存”的指针。