代码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. WebService实现文件上传下载

    一:服务端:一个普通java web工程 package com.wzh.file; import com.sun.xml.ws.developer.StreamingAttachment; impo ...

  2. jQueryMobile之listview

    效果如下: data-inset="true":为圆角 data-filter="true":带着过滤输入框 <!DOCTYPE html> < ...

  3. 来一个可能防止恶意采集和爬虫的SH

    没办法,公司的要求,还有,一些山寨爬虫完全不够我们运维人员的感觉, 一天爬虫搞个三四十万的LOG,那我只好干了.. 人家GOOGLE,BAIDU,一天大约也就五六千吧.. 有一个小的SSH技巧,是判断 ...

  4. 实用C51编程的高级技巧(C51编程)

    一.C51热启动代码的编制 void main() { char data *HotPoint=(char *)0x7f; if((*HotPoint==0xaa)&&(*(--Hot ...

  5. Linux下根据进程的名字杀死进程

    以前是写了一个bash,通过ps,grep 和awk配合搜索PID再kill掉进程.果然以前傻,不知道解决问题之前先google,原来直接就有相关的pkill -f "process_nam ...

  6. Linux系统编程(25)——终端

    在Linux系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端.控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动 ...

  7. SDL2.0 学习笔记-1 windows下的第一个测试程序

    SDL全称是Simple DirectMedia Layer,是一个开源的.跨平台(win32,linux,mac)的多媒体开发c语言库. 官方网站 http://www.libsdl.org/ 第一 ...

  8. City Tour

    Description Alice想要从城市A出发到城市B,由于Alice最近比较穷(不像集训队陈兴老师是个rich second),所以只能选择做火车从A到B.不过Alice很讨厌坐火车,火车上人比 ...

  9. HDU_2014——计算平均分

    Problem Description 青年歌手大奖赛中,评委会给参赛选手打分.选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分.   Input 输入数据有多组,每 ...

  10. 【HDU2224】The shortest path(双调欧几里得dp)

    算法导论上一道dp,挺有趣的.于是就研究了一阵. dp(i, j)代表从左边第一个点到第i个点与从从左边最后一个点(即为第一个点)到j点的最优距离和.于是找到了子状态. 决策过程 dp[i][j] = ...