Chinaunix首页 | 论坛 | 博客
  • 博客访问: 40632
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 82
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-19 14:23
个人简介

本尊不死,尔等终究为奴...

文章分类

全部博文(8)

文章存档

2016年(1)

2015年(4)

2013年(3)

我的朋友

分类: C/C++

2013-07-20 10:25:38

GetMemory经典示例

        //NO.1程序首先申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*strNULL中的值为0),调用函数的过程 中做了如下动作:1申请一个char 类型的指针p,2把str的内容copy到了p里(这是参数传递过程中系统所做的),3p指针申请了100个空间,4返回Test函数.最后程序把字符 hello world拷贝到str指向的内存空间里.到这里错误出现了!str的空间始终为NULL而并没有实际的空间.深刻理解函数调用的第2步,将不难发现问题 所在!


点击(此处)折叠或打开

  1. void GetMemory(char *p)
  2. {
  3.    p = (char*)malloc(100);
  4. }
  5. void Test(void)
  6. {
  7.    char *str = NULL;
  8.    GetMemory(str);
  9.    strcpy(str, "hello world");
  10.    printf(str);
  11. }

请问运行Test函数后会是什么样的结果?


        //NO.2
程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存 空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.


点击(此处)折叠或打开

  1. char *GetMemory(void)
  2. {
  3.    char p[] = "hello world";
  4.    return p;
  5. }
  6. void Test(void)
  7. {
  8.    char *str = NULL;
  9.    str = GetMemory();
  10.    printf(str);
  11. }
       
        //NO.3
:问题同NO.1,正确答案为可以打印出hello.但内存泄漏了!


点击(此处)折叠或打开

  1. void GetMemory(char **p, int num)
  2. {
  3.    *p = (char*)malloc(num);
  4. }
  5. void Test(void)
  6. {
  7.    char *str = NULL;
  8.    GetMemory(&str, 100);
  9.    strcpy(str, "hello");
  10.    printf(str);
  11. }


//NO.4 申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个 不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会 避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.


点击(此处)折叠或打开

  1. void Test(void)
  2. {
  3.    char *str = (char*)malloc(100);
  4.    strcpy(str, "hello");
  5.    free(str);
  6.    if (str != NULL)
  7.    {
  8.       strcpy(str, "world");
  9.      printf(str);
  10.    }
  11. }
  12. void GetMemory1(char *p)
  13. {
  14.     p = (char *)malloc(100);
  15. }
  16. void Test1(void)
  17. {
  18.     char *str = NULL;
  19.     GetMemory1(str);
  20.     strcpy(str, "hello world");
  21.     printf(str);
  22. }
  23. //str一直是空,程序崩溃
  24. char *GetMemory2(void)
  25. {
  26.     char p[] = "hello world";
  27.     return p;
  28. }
  29. void Test2(void)
  30. {
  31.     char *str = NULL;
  32.     str = GetMemory2();
  33.     printf(str);
  34. }
  35. char *GetMemory3(void)
  36. {
  37.      return "hello world";
  38. }
  39. void Test3(void)
  40. {
  41.     char *str = NULL;
  42.     str = GetMemory3();
  43.     printf(str);
  44. }
  45. //Test3 中打印hello world,因为返回常量区,而且并没有被修改过。Test2中不一定能打印出hello world,因为指向的是栈。
  46. void GetMemory4(char **p, int num)
  47. {
  48.     *p = (char *)malloc(num);
  49. }
  50. void Test4(void)
  51. {
  52.     char *str = NULL;
  53.     GetMemory3(&str, 100);
  54.     strcpy(str, "hello");
  55.     printf(str);
  56. }
  57. //内存没释放
  58. void Test5(void)
  59. {
  60.     char *str = (char *) malloc(100);
  61.     strcpy(str, "hello");
  62.     free(str);
  63.     if(str != NULL)
  64. {
  65.    strcpy(str, "world");
  66.    printf(str);
  67. }
  68. }
  69. //str为野指针,打印的结果不得而知
  70. void Test6()
  71. {
  72.     char *str=(char *)malloc(100);
  73.     strcpy(str, "hello");
  74.     str+=6;
  75.     free(str);
  76.     if(str!=NULL)
  77.     {
  78.         strcpy(str, "world");
  79.         printf(str);
  80.     }
  81. }
  82. //VC断言失败,运行错误
  83.  
  84. 另转一则:
  85. char *GetMemory3(int num)
  86. {
  87.     char *p = (char *)malloc (sizeof(char) * num);
  88.     return p; //返回指针 p
  89. }
  90.  
  91. void Test3(void)
  92. {
  93.     char *str = NULL;
  94.     str = GetMemory3(100); //这里指针 str也和指针 p的指向一样的内存块。
  95.     strcpy(str, "hello");
  96.     cout<< str << endl;
  97.     free(str); //这里最终只是释放了str指向的内存块,对于str指针 依然还是指向那块内存,看了一些资料说应该加一句str=0;那指针 p呢?p也依然在指向那块内存啊。
  98. }


1. 函数进入Test3():

char* str = NULL;

======================
变量   变量的地址         变量的值(内容
)
str    0x0013fe8c         0


2. 
str = GetMemory3(..)=====>
char *p = (char *)
malloc 
(sizeof(char) * num);
将分配的内存起始地址(0x003a60b0)赋给栈变量p,

===============================================
变量     变量的地址       变量的值(内容
)
p        0x0013fda8       0x003a60b0


3. 
GetMemory3(..)返回, p的值
(0x003a60b0)
拷贝给str, 栈变量p生命结束释放其所占栈内存

(
地址0x0013fda8)

=================================================
变量       变量的地址     变量的值(内容
)
str        0x0013fe8c      0x003a60b0


4. free(str):  
释放str指向的内存(0x003a60b0开始的内存空间
)

5. 
推出Test3(),  栈变量str生命结束释放其所占栈内存

(
地址0x0013fe8c)


阅读(1179) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~