关于内存,指针的一点思考

下面四个例子程序摘自林锐的c++/c高质量编程P373

程序一.

void GetMemory(char *p)

{

p  = (char *) malloc(100);

}

void Test(void)

{

char *str = NULL;

GetMemory(str);//这里函数调用str,但GetMemory()的操作对象是指针str的拷贝

strcpy(str,"Hello World!");

printf(str);

}


由图可见,str的指向并未发生变化,变化的只是str的拷贝p指针的指向。在用指针传递参数时,我们可以改变原指针指向的内容(*p),但不能改变原指针的地址(p)。

所以,程序一会崩溃。str一直是NULL。



程序二.

char *GetMemory(void)

{

char p[ ] = "Hello World!";

return p;

}

void Test(void)

{

char *str = NULL;

str = GetMemory();

printf(str);

}

GetMemory()返回的是指向“栈内存”的指针,子程序调用结束后p所指向的字符串以及p自身都将销毁,返回的p指向不明。所以可能输出乱码。


程序三.

void  GetMemory(char **p,int num)
{
*p = (char *)malloc(num);
}
int main()
{
char *str = NULL;
GetMemory(&str,100);
strcpy(str,"Hello World!");
printf(str);

return 0;

}

可以输出Hello World!,但是会发生内存泄漏。子函数GetMemory(char **p,int num)第一个参数是二级指针,即指向指针的指针,目的是确保传入是str指针的地址,而不是单纯的拷贝。申请的内存是置于堆中的,子程序调用结束后不会销毁。

程序四.

int main

{

char *str = (char*)malloc(100);

strcpy(str,"Hello World!")
free(str);
if(str!=NULL)
{
strcpy(str,"Hello World!")
printf(str);

}

return 0;

}

str被free后成了野指针,且不是NULL,所以if(str!=NULL)这句无法起到监测的作用,执行strcpy函数时会篡改动态存储区中的内容,后果难以预料。

为了避免出现野指针,通常我们需要将指针初始化为NULL,用完后也为其赋值为NULL。这句引自http://www.cnblogs.com/evisie/archive/2011/08/04/2128051.html


猜你喜欢

转载自blog.csdn.net/gin077/article/details/42872163