1、

#include<stdio.h>
#include<string.h>
void GetMemory(char *p)
{
p=(char *)malloc(100);

}
int main()
{
char *str=“abc”;  // 我们不用 NULL,用 abc 试一试
GetMemory(str);

printf("%x",str);   //  这里自己添加这一句,调试发现 这里仍然是 NULL 也就是 0x0000000 所以str 仍然是空指针
strcpy(str,"Hello world");   //  执行到这一步,失败不懂啊?? why ,
printf(str);

}

常量区        
00420028 abc                                              str 自身地址 也就是&str   0012ff7c 00420028
             str 存储的值(也就是地址00420028)也传递给 p     
        &p  p 自身地址 存储在 栈区    地址为 0012ff2c    00420028 
           
           

执行 p= (char *)malloc(100);时候

        p 本身地址没有变,依旧是 &p    0012ff2c,但是存储的内容变了 00431c60
           
           
           
           
           

懂了伐???? str 只是一个 int 型的而已,存放 'a'; 00:47:42   睡觉 !!!!

解释: GetMemory( )在调用的时候 str 进行地址传递的时候,会使得 P 指针存储的地址为 NULL 也就是 0x0000 0000

但是这里的 GetMemory 实际上是对调用函数里面的 P指针分配了内存而已,p地址随机的 这里是 0x00431ca0

GetMemory(str),实质是对p的操作,并没有对str操作,函数结束后p撤销,因此不会产生新的内存空间,str仍然是一个空指针。所以失败。

2、

char *GetMemory()

{

char p[]="Hello World";

return p;

}

void Test()

{

char * str=NULL;

str=GetMemory();

printf(str);

}

这里 调试 str=0x000000

调用函数的p指针地址为 0x0012ff18 ,然后内存里存储的是 Hello world 不能理解的是 这些 0x48 x065 0x6c 是哪来的,为什么不是 0x0012ff18 是存在堆栈里面吗?不太懂。看第三个解释,可以说明是 对的 helll world 就是放在了栈区,所以调用后释放了内存,消失了。

 

return p ; 这里返回了 p 的地址,也就是说 str=GetMemory()把 P的地址 0x12ff18 传给了 str ;

看起来 这一步好像是对的 ,但是只是传递的地址,而后面的“helll world ”在执行完 调用函数后被释放了,在执行下两步就知道了

看出来了 str 里面输出的 是 0  还有个箭头符号。 所以说是错的。

网上解释: 实质:当一个函数调用结束后会释放内存空间,释放它所有变量所占用的空间,所以数组空间被释放掉了,也就是说str所指向的内容不确定是什么东西。但是返回的指针指向的地址是一定的

3、

#include<stdio.h>
#include<string.h>

char *GetMemory()
{
return "hello world";
}
void main()
{
char * str=NULL;
str=GetMemory();
printf(str);
}

输出正确,为什么会这样呢? 因为是这样的:

解释: 网上的: 实质:本例打印hello world,因为返回常量区,而且并没有修改过。在上一个例子中不一定能打印hello world,因为指向的是栈区。

这里我们要 深入的学习 return 的用法了,这当然又是另外一个故事了啊!!!

4、

#include<stdio.h>
#include<string.h>

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

                     
                    str  自身地址  0012ff7c NULL
                       
                    p     自身地址 &p     0012ff28   p=0012ff7c
                       
                    执行过*p=(char *)malloc(num);后,也就是为  0012ff7c 地址分配内存单元,那么   地址 0012ff7c 里面存放地址单元 00431c60
                       
00431c60                   那么 str  存储 00431c60
                       
                       
                       
                       
 地址        P指针  0012FF28 0012FF7C str  0x00431ca0
存储数值         0012FF7C *p =00431ca0 **p =  hell0 

从图可以看出来,可以正确的打印Hello但是内存泄露了,在GetMemory()中使用了malloc申请内存,但是在最后却没有对申请的内存做任何处理,因此可能导致内存的泄露,非常危险。

不是很理解,要仔细学习 **P ,指向指针的指针的用法???? 有点犀利糊涂

09:12:50

网上理解: 之所以定义二级指针**P,不是为了使用**P表示指向的值,而是为了使用*P来存储存储值的那个单元的地址,也就是 00431ca0

一开始传参数时,存储str的单元地址赋值给P,

这样P中单元存储的就是STR的地址,

从而,*P 表示的就是STR的值

5、

#include<stdio.h>
#include<string.h>

void main()
{
  char *str=(char *)malloc(100);   // 分配内存
  strcpy(str,"Hello");                 // 复制字符串
  printf(str);                           // 输出字符串 基本没有问题
  free(str);                            // 指针被释放后,成了野指针,这里 不再是 NULL ,(一般来说应该不是吧)
  if (str!=NULL)                    
  {
    strcpy(str,"World");         // 不是NULL ,那么继续执行,str 开始的 hello 又被 world 给覆盖了
    printf(str);                     // 输出的 是  world  
  }
}

网上解释: 申请空间,拷贝字符串,输出字符串,释放空间,前四步操作都没有问题,到了if语句里的判断条件开始出错了。因为一个指针被释放了之后其内容并不是NULL,而是一个不确定的值,所以if语句是被执行的,这也是著名的“野”指针问题。

自己思考了一下,如果真的是野指针,也不一定是输出 world ,应该不太确定。

最新文章

  1. 【.NET深呼吸】(WPF)跨窗口完成绑定
  2. (转)配置Log4j(很详细)
  3. 基于C/S架构的3D对战网络游戏C++框架 _【不定期更新通知】
  4. OI省选算法汇总
  5. 像素图的实时光照 Lighting on Pixel Art
  6. JS全局函数parseInt和parseFloat
  7. Javascript异步请求你能捕获到异常吗?
  8. Unable to open c
  9. 复制virtualenv环境到其他服务器环境配置的方法
  10. JPA EntityManagerFactory Vs Hibernate’s SessionFactory
  11. Git本地项目上传 &amp; SourceTree &amp; GitHub 简单使用
  12. CSS3新增伪类汇总
  13. BSGS及扩展BSGS算法及例题
  14. Thymleaf js直接获取后台传过来的对象或者对象的属性以及map
  15. vue 中给组建绑定原生事件@click.native=&quot;&quot;
  16. Python学习之路&mdash;&mdash;&mdash;&mdash;Day03
  17. DBA记录-数据库管理员需要掌握的内容
  18. C#编程(十三)----------方法重载
  19. 10篇写给Git初学者的最佳教程(转)
  20. 继电器是如何成为CPU的(1)【转】

热门文章

  1. C#窗体:关于DataGridView的数据源绑定字符串两个值得注意的问题
  2. wget ftp
  3. 关于cocoa框架,你所要知道的一切(苹果官方文档,cocoa框架核心竞争力,必须收藏!)
  4. 在VC6.0中编译头文件时产生moc文件
  5. Spring中Quartz的最精简的配置
  6. threading多线程
  7. windows下安装和配置mongoDB
  8. Java学习-010-创建文件夹源代码
  9. Windows-005-显示隐藏文件
  10. .emacs