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 ,应该不太确定。

关于内存 GetMemory( ) 笔试分析的更多相关文章

  1. JVM内存区域异常分析

    在Java虚拟机规范描述中,除程序计数器外,其他几个运行时区域都有可能发生OutOfMemoryError异常.接下来将对各区域分别进行分析介绍,内容包括触发各区域OutOfMemoryError异常 ...

  2. Memcached内存管理模型分析

    Memcached 是一个高性能的分布式内存对象缓存系统,它通过在内存中缓存数据和对象来减少读取数据库的次数,从而减轻RDBMS的负担,提高服务的速度.提升可扩展性.本文将基于memcached1.4 ...

  3. Keil C动态内存管理机制分析及改进(转)

    源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...

  4. linux内存源码分析 - 零散知识点

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 直接内存回收中的等待队列 内存回收详解见linux内存源码分析 - 内存回收(整体流程),在直接内存回收过程中, ...

  5. linux内存源码分析 - 内存回收(整体流程)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 当linux系统内存压力就大时,就会对系统的每个压力大的zone进程内存回收,内存回收主要是针对匿名页和文 ...

  6. linux内存源码分析 - 内存压缩(同步关系)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 最近在看内存回收,内存回收在进行同步的一些情况非常复杂,然后就想,不会内存压缩的页面迁移过程中的同步关系也 ...

  7. linux内存源码分析 - 内存压缩(实现流程)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 本文章最好结合linux内存管理源码分析 - 页框分配器与linux内存源码分析 -伙伴系统(初始化和申请 ...

  8. linux内存源码分析 - SLUB分配器概述

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ SLUB和SLAB的区别 首先为什么要说slub分配器,内核里小内存分配一共有三种,SLAB/SLUB/SLOB ...

  9. linux内存源码分析 - SLAB分配器概述【转】

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 之前说了管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配给申请 ...

随机推荐

  1. 用正则验证字符串格式,形如:A)XXX B)XXXX C)XXX

    今天遇到个小功能,要验证某个英文选项是否正确,例如:A)accumulate B)circling C)communities  D)competition  E)domestic F)financi ...

  2. 出现upstream sent too big header while reading response header from upstream错误

    一个POS系统,出现upstream sent too big header while reading response header from upstream错误. 1.反向代理端,可以放到se ...

  3. 20145211 《Java程序设计》课程总结——桃花流水窅然去

    每周读书笔记链接汇总 20145211 <Java程序设计>第1周学习总结--小荷才露尖尖角 20145211 <Java程序设计>第2周学习总结--桃花依旧笑春风 20145 ...

  4. 【C++】利用指针实现通过函数改变多个参数的值

    写惯了python,对于C++的语法越来越生疏,不同于python中函数可以return多个变量,C++的函数要想返回多个参数可以利用指针实现. 因为在函数内部的变量都是局部变量,所以当参数传入函数中 ...

  5. 用代码调用Storyboard里面的viewController

    今天在帮助群里的一个朋友弄pop事件,在他那边,当前的viewcontroller,不能pop出去. 初步估计,他的ViewController层级多,他自己没有理清. 因为pushViewContr ...

  6. thinkPHP 接支付宝及时到账接口

    支付宝及时到帐接口,现在整理以下: 1.先将支付宝提供的公共类库函数库文件防盗thinkPHP的Vender目录下建的一个alipay文件下,以便之后的调用. //四个文件我分别给他们改了下名字,因为 ...

  7. 让DIV中的内容水平和垂直居中

    让一个层水平垂直居中是一个非常常见的布局方式,但在html中水平居中使用margin:0px auto;可以实现,但垂直居中使用外边距是无法达到效果的.(页面设置height:100%;是无效的),这 ...

  8. jQuery 插件 获取URL参数

    jQuery 获取URL参数的插件 jQuery Url Query String 下载地址:http://plugins.jquery.com/getUrlQueryString.js/   var ...

  9. 8、JavaScript深入浅出——数据类型

    一.六种数据类型 Javascript是弱类型. 五种原始类型和一种对象类型: number String boolean null undefined Object 二.隐式转换 +与-的运算举例: ...

  10. JDK和Tomcat的安装与配置

    1       JDK的安装 2       JDK的配置 3       JDK安装成功的验证 4       Tomcat的安装 (1)     解压” apache-tomcat-6.0.35. ...