Eg:
void GetMemory(char *p,int num)//直接把指针传递给一个函数
{
p = (char *) malloc(num*sizeof(char));
}
void main(void)
{
char * str = NULL;
GetMemory(str,10);//str为局部变量,当传递给函数时,函数不能真正使用str,用的只是str的一个备份,str的值不变。
strcpy(str,"hello");//此处str的值仍然为NULL,malloc分配的内存地址并没有赋给str。如何实现呢,执行到这发生访问冲突
free(str);
}
采用return语句实现:
char * GetMemory(char *p,int num)
{
p = (char *) malloc(num*sizeof(char));
return p;
}
采用二级指针实现:
void GetMemory(char * *p,int num)
{
*p = (char *) malloc(num*sizeof(char));//直接给str赋值了
}
void main(void)
{
char * str = NULL;
//str = GetMemory(str,10);//str为局部变量,当传递给函数时,函数不能真正使用str,用的只是str的一个备份,str的值不变。
GetMemory(&str,10);//直接把str的地址传过去了
strcpy(str,"hello");//此处str的值仍然为NULL,malloc分配的内存地址并没有赋给str。如何实现呢,执行到这发生访问冲突
free(str);
}
Eg:
char * (* fun1)(char * p1,char * p2);
fun1为指针变量,指向一个带两个指针参数,返回值为char *类型的函数。
堆:由malloc系列函数或new操作符分配的内存,其生命周期由free或delete决定,在没有释放前一直存在,直到程序结束。使用灵活,空间较大,易出错。
栈:即通常所说的堆栈,保存局部变量。函数运行结束时自动销毁。效率高,空间小。
静态区:保存自动全局变量和static变量(局部、全局),在整个程序的生命周期内都存在,由编译器在编译时分配。
不管什么时候,在使用指针之前一定要确保指针是有效的。在头文件assert.h中有宏assert来检验。assert(NULL!=p)对参数进行检验,在非参数的情况下使用if(NULL!=p)来检验,这就要求指针p在定义时被初始化为NULL。Assert宏只在Debug版本上起作用,在Release版本中被编译器完全优化掉。
assert后括号里值为假时,则程序终止运行,并提示出错,为真,则继续运行。
会产生内存泄漏的内存就是堆上的内存,也就是用malloc系列函数或new操作符分配的内存。malloc分配内存如果出错则返回NULL,用if(NULL!=p)验证。
D. malloc与free必须配对使用。
文章评论(0条评论)
登录后参与讨论