代码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. shell脚本实例一,移动文件夹中大于2000B的文件到另一个文件夹

    shell脚本能帮我们简化linux下的一些工作,现在有个需求,把TMPA文件夹下大于2000B的文件都移动到TMPB下 #! /bin/bash function movefiles() { ` d ...

  2. Linux查看机器是多少位

    命令: file /bin/ls或者file /sbin/init 示例: 如上所示,我的机器是32位的.

  3. DBUtils框架

    一.O-R Mapping 简介    一]概念:可以理解为对象和数据库的映射.    二]常用O-R Mapping映射工具        1)Hibernate(全自动框架)        2)l ...

  4. HDU5141--LIS again (LIS变形)

    题意一个序列的LIS为MAX, 求连续子序列的LIS为MAX的个数. 先求出LIS,记录以a[i]结尾的LIS的长度,以及LIS起始位置(靠右的起始位置). 然后线性扫一遍,,线段树与树状数组的差距还 ...

  5. 教你正确地利用Netty建立连接池

    一.问题描述 Netty是最近非常流行的高性能异步通讯框架,相对于Java原生的NIO接口,Netty封装后的异步通讯机制要简单很多. 但是小K最近发现并不是所有开发人员在使用的过程中都了解其内部实现 ...

  6. Java中静态数据的初始化顺序

    Java的类中的数据成员中包含有静态成员(static)时,静态数据成员的初始化顺序是怎样的呢? [程序实例1] import java.util.*; import java.lang.*; imp ...

  7. 汉得第二次考核答案整理(通信,IO,文件等)

    1, (8 分 ) 使用程序从网上下载 pdf, 网址为http://files.saas.hand-china.com/java/target.pdf,保存在本地,编程时使用带缓冲的读写,将需要保证 ...

  8. 文件上传插件Uploadify在Struts2中的应用,完整详细实例

    —>最近由于项目需要使用到一个上传插件,在网上发现uploadify挺不错,所以决定使用它,但是官网文档和例子是php的,而项目是SSI框架的,所以自己对uploadify在struts2中的使 ...

  9. Win8.1OS64位oracle11安装配置及PL/SQL Developer怎样连接64位oracle

    Oracle 为什么选择oracle 1.oracle可以在主流的平台上执行,而相对于sql server仅仅支持windows,而windows在wr手里攥着呢,所以你懂的.在安全性上来讲,非常多地 ...

  10. Android 中文 API (40) —— RatingBar

    Android 中文 API (40) —— RatingBar 前言 本章内容是 android.widget.RatingBar,译为"评分条",版本为Android 2.2 ...