Referenced from website -----------------------------------------------------
程序的可用内存有三种:静态存储区、栈存储区、堆存储区。静态存储区是全部变量和static变量占据的,在程序开始运行之前就分配好了,它们从不释放;栈存储区在函数调用前分配,函数调用返回时释放;而堆存储区的分配释放完全在程序员手中,你用malloc/free进行分配与释放。
每个变量都要有它的内存分配,如:
static int global_var;
即是在静态存储区分配一个整型变量;而
void func(void)
{
char local_var;
...
}
则是在栈存储区分配一个字符变量。
结构体并没有什么不同,设有结构体定义:
struct stu
{
char sex;
long num;
};
则下面的定义:
static struct stu a;
将在静态存储区分配一个结构体变量,大小为sizeof(struct stu);同样地,
void func(void)
{
struct stu b;
...
}
则是在栈存储区分配一个结构变量,大小也为sizeof(struct stu)。
对于指针,情况有些微妙,难以理解。指针变量本身,它也可以有上面三指分配:如
static char *c;
在静态存储区分配一个“字符指针变量”,大小为sizeof(char *);而
void f(void)
{
long *d;
...
}
在栈存储区分配一个“long长整形指针变量”,大小为sizeof(long *)。它们分配的是“指针变量”本身,而不是指针变量所指向的内存块,指针变量所指向的内存块同样必须分配,它同样的可以有三种分配,如你说的:
void f(void)
{
struct stu a, *p;
...
}
这里在栈存储区分配了一个“stu结构体变量”和一个“stu结构体指针变量”,它们都没有初始化,即指针变量p的指向是不确定的,此时你不能用变量p读写数据,如果要初始化,可以有p = &a;这样就令p指向了一块已分配的内存,就是栈上的“stu结构体变量”a。由于栈存储区在函数调用返回时空间被自动释放,因此下面的程序是错的:
struct stu *f(void)
{
struct stu a, *p;
p = &a;
return p;
}
设有调用struct stu *x = f();则调用f返回时,x所指向的内存块已被自动释放,因此是错误的!
此时堆存储区来大显身手了,
struct stu *g(void)
{
struct stu *p;
p = malloc(sizeof(struct stu));
return p;
}
同样返回一个stu结构体指针,但它所指向的内存块是在堆上分配的,在函数g返回时不会自动释放,从而你可以继续使用,在用完之后再使用free释放之:
struct stu *y = g();
... /* do something */
free(y);
--------------------------------------------------------------------------------------------------------------
现在的理解是基本变量int. char...根据声明的区域和方式不同,分别存储于静态区,堆,栈。内存静态区和栈上的变量会在程序结束和函数调用后自动释放,但是堆变量在使用完后需要人工释放free(ptr)。指针也是变量,也符合这个规律。特别的,int *p; p=malloc(sizeof(int)); ** DO STH**; free(p); 在free()执行过后*p还是指向同一块内存,但是那块内存里面已经没有内容了。 对于堆对象,在使用完后,总是需要free().