首先,常量和全局变量以及静态变量都存储于静态存储区,而局部变量在栈区;
其次,内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
一,char *GetMemory()
{
char *p= "hello";
return p;
}
int main()
{
char *str=NULL;
str=GetMemory();
printf("%s",str);
return 0;
}
=>上述结果可输出hello,因为p指针指向的“hello”是字符串常量,生存期为整个程序运行阶段。返回指针p给指针str等于将str指向“hello”的首地址,虽然GetMemory返回时指针p被释放,但处于静态存储区的字符串常量没有变化,因此可输出hello。
二,
char *GetMemory()
{
char *p;
char a[]="hello";
p = a;
return p;
}
int main()
{
char *str=NULL;
str=GetMemory();
printf("%s",str);
return 0;
}
=>上述结果输出乱码,原因是指针p指向的地址为局部数组a的首地址,返回指针p给指针str等于将str指向a的首地址,当GetMemory返回时指针p和数组a都被释放,因此输出为乱码。
三,
char *GetMemory()
{
char *p;
char a[10] = "hello";
p = malloc(10);
memcpy(p,a,sizeof(a));
return p;
}
int main()
{
char *str=NULL;
str=GetMemory( );
printf("%s",str);
return 0;
}
=>上述结果输出hello,因为GetMemory中用到动态申请内存,由malloc申请的内存属于从堆上分配,其生存期由我们决定,且让指针p指向动态申请的这块内存首地址。当GetMemory返回时指针p和数组a都被释放,但在堆上的这块内存没变化(存储着hello这个字符串),因此可输出hello。
四,关于指针的传递上述两个函数中,GetMemory返回指针p给str,意思是让str指向指针p所指向的地址空间。又如 void GetMemory(char *p, int num)
{
p = malloc[num];}void Test(void){ char *str = NULL; GetMemory(str, 100); // str 仍然为 NULL strcpy(str, "hello"); // 运行错误 free(str); }=>此例中将指针str作为实参传给形参p,表示让指针p指向指针str所指向的地址空间。在函数GetMemory中为指针p新申请一块内存,其结果是让指针p指向新申请的内存地址,而这个做法并不改变指针str的指向,因此Test函数中运行完GetMemory之后str仍然为NULL。这就如同下边的函数void GetMemory(char *p, int num)
{//进入这个函数后形参p指向实参地址
char a = 9;
p = &a;//此处将p指向变量a的地址
}五,上述四中的例子不能申请内存,如果非要用指针申请内存可用指向指针的指针,或者三中的指针函数也行。void GetMemory2(char **p, int num){ *p = new char[num];}void Test2(void){ char *str = NULL; GetMemory2(&str, 100); // 注意参数是 &str,而不是str strcpy(str, "hello"); cout<< str << endl; free(str); }
文章转自:http://blog.csdn.net/celerylxq/article/details/7637176