代码1:

void GetMemory(char *p)
{
p = (char*)malloc(100);
}
int main(int argc, char *argv[])
{
char *str = NULL;
GetMemory(str);
strcpy(str, "Hello");
return 0;
}

str没有得到分配内存的地址值。 
内存空间状态:首先申请了四个字节的栈空间,存放str指针,此时str的值为0,存放str的这块内存的地址值为0x0012ff7c。调用函数 GetMemory,指针P入栈,也分配了四个字节的栈空间,P被赋str的值即此时P的值也为0,存放指针P的内存地址是0x0012ff2c。然后将新开辟的100个字节的内存空间地址赋给P,此时P的值为0x00372b70。函数调用结束时str的值仍为0,str并没有得到那块100个字节的内存空间地址值!

代码2:

void GetMemory(char **p)
{
*p = (char*)malloc(100);
}
int main(int argc, char *argv[])
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "Hello");
return 0;
}

str可以得到分配内存的地址值。 
内存空间状态:首先申请了四个字节的栈空间,存放str指针,此时str的值为0,存放str的这块内存的地址值为0x0012ff7c。调用函数 GetMemory,指针P入栈,也分配了四个字节的栈空间,此时P是一个二级指针,存放了指针str的地址值,即P的值是0x0012ff7c,存放指针P的内存空间的地址值是0x0012ff2c。然后将新开辟的100个字节的内存空间地址值0x00372b70赋给*P,即str,所以str的值为 0x00372b70。函数返回时str的值为分配的100个字节的内存空间的地址!

代码3:

void GetMemory(char **p)
{
// 这条语句编译出错,将一个二级指针指向分配的地址了
// p = (char*)malloc(100);
// 可以使用强制转换,但程序crash
p = reinterpret_cast<char**>(malloc(100));
}
int main(int argc, char *argv[])
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "Hello");
return 0;
}

str不能得到分配内存的地址值,程序crash。 
如果在GetMemory函数中使用如下语句 p = (char*)malloc(100); 会出现编译出错,原因是不能将一个二级指针指向分配的内存空间地址。如果使用强制转换 p = reinterpret_cast<char**>(malloc(100)); 编译可以通过,但是会造成程序崩溃。

代码4:

void GetMemory(char *p)
{
p = (char*)malloc(100);
}
int main(int argc, char *argv[])
{
char *str = NULL;
GetMemory(&str); // 这条语句会编译出错,将一个指针地址值传给了一级指针
strcpy(str, "Hello");
return 0;
}

str不能得到分配内存的地址值,编译出错。 将一个指针的地址值传给了一级指针,非法!

void GetMemory1(char *p)
{
    p = (char *)malloc(100);
}

void Test1(void) 
{
    char *str = NULL;
    GetMemory1(str); 
    strcpy(str, "hello world");
    printf(str);
}
//str一直是空,程序崩溃
char *GetMemory2(void)

    char p[] = "hello world";
    return p;
}
void Test2(void)
{
    char *str = NULL;
    str = GetMemory2(); 
    printf(str);
}
char *GetMemory3(void)

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

//Test3 中打印hello world,因为返回常量区,而且并没有被修改过。Test2中不一定能打印出hello world,因为指向的是栈。

void GetMemory4(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test4(void)
{
    char *str = NULL;
    GetMemory3(&str, 100);
    strcpy(str, "hello"); 
    printf(str); 
}
//内存没释放

void Test5(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str); 
    if(str != NULL)
{
   strcpy(str, "world"); 
   printf(str);
}
}
//str为野指针,打印的结果不得而知

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

GetMemory 函数解析的更多相关文章

  1. [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")

    javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢?   原因在于: ...

  2. PHP json_decode 函数解析 json 结果为 NULL 的解决方法

    在做网站 CMS 模块时,对于模块内容 content 字段,保存的是 json 格式的字符串,所以在后台进行模块内容的编辑操作 ( 取出保存的数据 ) 时,需要用到 json_decode() 函数 ...

  3. Matlab中bsxfun和unique函数解析

    一.问题来源 来自于一份LSH代码,记录下来. 二.函数解析 2.1 bsxfun bsxfun是一个matlab自版本R2007a来就提供的一个函数,作用是”applies an element-b ...

  4. socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  5. sigaction函数解析

    http://blog.chinaunix.net/uid-1877180-id-3011232.html sigaction函数解析  sigaction函数的功能是检查或修改与指定信号相关联的处理 ...

  6. driver_register()函数解析

    driver_register()函数解析 /** * driver_register - register driver with bus * @drv: driver to register *  ...

  7. async函数解析

    转载请注明出处:async函数解析 async函数是基于Generator函数实现的,也就是说是Generator函数的语法糖.在之前的文章有介绍过Generator函数语法和异步应用,如果对其不了解 ...

  8. tf.train.shuffle_batch函数解析

    tf.train.shuffle_batch (tensor_list, batch_size, capacity, min_after_dequeue, num_threads=1, seed=No ...

  9. oracle中next_day()、last_day()函数解析

    oracle中next_day()函数解析 Sql代码 当前系统时间的下一星期一的时间select   next_day(sysdate,1) from dual NEXT_DAY(date,char ...

随机推荐

  1. [工具]前端自动化工具grunt+bower+yoman

    安装过程 安装nodejs 安装grunt,bower,yoeman 命令:(-g 表示全局安装,否则安装到当前目录下) npm install -g grunt-cli npm install -g ...

  2. 2015.9.11模拟赛 codevs 4160【会玩的】

    题目描述 Description hzwer真的很会玩啊…他有一个n*m的方格,每次可以给方格添加一整行或一整列,但是不能删除.现在他想要让总格子数超过k个,但是又想让总格子数尽可能小.请找出这时的n ...

  3. DPDK2.1开发者手册3-4

    环境抽象层EAL 环境抽象层的任务对访问底层资源例如硬件和内存提供入口.它提供了隐藏应用和库的特殊性性的通用接口.它的责任是初始化分配资源(内存,pci设备,定时器,控制台等等). EAL提供的典型服 ...

  4. 字符流;字节流;带缓冲的输入输出流;以及用scanner读文件

    概念: InputStream类是字节输入流的抽象类,是所有字节输入流的父类. OutputStream类是字节输入流的抽象类,是所有字节输出流的父类. In(可以理解为读)Out(可以理解为写) 一 ...

  5. sql server 2008 在安装了活动目录以后无法启动服务了

    软件环境: windows server 2008 r2 ms sql server 2008 r2 在安装活动目录以前,数据库是正常运行的. 安装了活动目录以后,数据库启动时就提示无法启动.出错的信 ...

  6. Linux下那些奇葩的命令

    相信喜爱编程,痴迷技术的你,肯定接触过甚至深爱着linux,甚至可能已经很熟悉linux了,可是linux那逗比的一面,你又知道多少. 本文!纯粹娱乐!不喜勿喷! 1.程序猿的愤慨! yes 当我们再 ...

  7. Oracle11g完全卸载步骤

    Oracle11g完全卸载步骤:1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务.2. 开始->程序->Oracle - OraHome ...

  8. rac 10g 加入节点具体解释

    目标: 当前我环境中是有两个节点RAC1和RAC2 节点.如今添加一个RAC3节点.   概要:为现有的Oracle10g RAC 加入节点大致包含下面步骤: 1. 配置新的server节点上的硬件及 ...

  9. 实战:推断mysql中当前用户的连接数-分组筛选

    #connets.sh #!/bin/sh #ocpyang@126.com #依据输入參数u或d来显示出相应的username或数据库名中用户的连接数. #也能够输入u 详细username或d 详 ...

  10. LDAP错误代码221

    ---------------------------命令方式启动失败报错-------------------------------[root@rusky bin]# ./dsadm start ...