GetMemory的典型例子分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014186096/article/details/49274561

NO.1

<span style="font-size:18px;">void GetMemory(char *p)
{
   p = (char*)malloc(100);
}
void Test(void)
{
   char *str = NULL;
   GetMemory(str);
   strcpy(str, "hello world");
   printf(str);
}
//运行Test函数后会是什么样的结果?</span>

解析如下:
<strong>/*
   </strong> 程序首先申请一个char类型的指针str,并把str指向NULL(即<span style="color:#ff0000;">str里存的是NULL的地址,*str为NULL中的值为0</span>)。
调用函数的过程 中做了如下动作:
1.申请一个char 类型的指针p;
2.把str的内容copy到了p里(这是参数传递过程中系统所做的);
3.为p指针申请了100个空间;
4.返回Test函数.最后程序把字符串hello world拷贝到str指向的内存空间里.<span style="color:#ff0000;">到这里错误出现了!str的空间始终为NULL而并没有实际的空间</span>.深刻理解函数调用的第2步,将不难发现问题所在!<strong>
*/</strong>


NO.2

char *GetMemory(void)
{
   char p[] = "hello world";
   return p;
}
void Test(void)
{
   char *str = NULL;
   str = GetMemory();
   printf(str);
}
解析如下:
/*
程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:
1.申请一数组p[]并将其赋值为hello world(数组的空间大小为12);
2.返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.
*/

NO.3

void GetMemory(char **p, int num)
{
   *p = (char*)malloc(num);
}
void Test(void)
{
   char *str = NULL;
   GetMemory(&str, 100);
   strcpy(str, "hello");
   printf(str);
}

解析如下:
/*
问题同NO.1,正确答案为可以打印出hello.但内存泄漏了!
*/

NO.4

void Test(void)
{
   char *str = (char*)malloc(100);
   strcpy(str, "hello");
   free(str);
   if (str != NULL)
   {
      strcpy(str, "world");
     printf(str);
   }
}

解析如下:
/*
申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,<span style="color:#ff0000;">因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值</span>.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会 避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.
*/




猜你喜欢

转载自blog.csdn.net/u014186096/article/details/49274561