zoukankan      html  css  js  c++  java
  • 关于malloc与字符指针的一些易错点

     有如下一段代码,意图把“zhongxiaoming"字符串赋值进以p为首地址的空间为15字节的内存空间,然后释放p所指向的内存,以免出现内存泄露。

    该代码出现几个问题,涉及到内存的赋值、malloc函数以及free函数的用法,以及字符串的相关知识。

     1 #include <stdio.h>

      2 #include <stdlib.h>
      3 
      4 int main()
      5 {
      6         char *p = (char*)malloc(15);
      7         int i=0;
      8         p="zhongxiaoming";
      9         for(;i<15;i++)
     10         {       
     11                 printf("p[%d]:%c ",i,*(p+i));
     12         }
     13         printf(" ");
     14         free(p);
     15         p=NULL;
     16         printf("ok ");
     17         return 0;

     18 }

    ===================================================================

    编译运行后:

    Love-Yan:pointertest MD101$ make
    gcc -o malloctest malloctest.c -g
    Love-Yan:pointertest MD101$ ./malloctest
    p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:np[12]:g p[13]:p[14]:p
    malloctest(3232) malloc: *** error for object 0x107a45f4e: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    Abort trap: 6

    可知道,pointer being freed was not allocated。意思是,意图释放的指针(p)没有被分配,这是什么意思呢?明明malloc了15字节的空间,怎么说没有被分配呢?

    原来:  

    malloc========================================

    8         p="zhongxiaoming"; 这行语句打乱了所有的计划,导致分配出来的15字节空间丢失了,内存泄露掉了。

     6         char *p = (char*)malloc(15);这时候的p才是15字节的真正主人。

    按照本意,我们采用strcpy就可以把“zhongxiaoming”拷贝进p指向的内存。不过,要记得加进<string.h>头文件哦。具体代码:

    strcpy(p,"zhongxiaoming");这样,p对应的连续15个内存地址就依次被赋值了,当然,只是赋值了strlen(“zhongxiaoming”)+1个字节,后面的应该保持不变,因为malloc分配出来的空间不会对内存进行初始化,而new操作符分配出来的会初始化。


    字符串、内存静态区======================================

    第八行代码把在静态区创建的字符串常量“zhongxiaoming”的首地址赋值给了p,此时,指针变量p的值发生了变化,不再是指向15个字节的首地址了。

    此时,可以通过p对字符串常量进行读的操作(无写操作,字符常量不允许修改,通常在静态区的内容,很多都是字符常量、整形常量等等,譬如int a=12;doule b=123.123123;

    这里的12和123.123123都是放在静态区的,他们都有个地址,这些常量与a、b对应,读a也就是读a对应的12.可是如果再有对a 的重新赋值,则常量区的12将会在某个时刻被系统回收掉,可以肯定的是,程序结束后肯定被释放掉了,呵呵。。。重新赋值a,如a=12312,则又在静态区创建12312与a对应,以此类推。),在此特别引申一点:

    指针对应的字符串的访问还可以通过poiner[i]操作符进行访问。当然,在这里是想把“zhongxiaoming”全部读出来。而p又指向其对应的地址(其实,用&(“zhongxiaoming”)可得到其地址),故我们可以通过p[i]进行访问,当然了,不能写哦,常量嘛,静态区嘛。。。那我们就这样完成了对常量区字符串“zhongxiaoming”的读操作啦。当然,这是没有修改过的源代码的功能。

    free===================================================

    按照没有修改过的源代码,直接就free(p),也太夸张了吧,把p(也就是&(“zhongxiaoming”)对应的内存释放),这是要逆天了?想去释放静态区的内存。。嘿嘿,这可是系统自己的事,最好还是别干预了。所以,系统报错。。。说,malloctest(2617) malloc: *** error for object 0x107b27f48: pointer being freed was not allocated。也就是说,这不是你分配的内存,这段内存不归你管。。。

    修改代码==================================================

    而加入strcpy的新代码,要对p对应的内容进行访问也就是有【】操作符或者*(p+i)了,千万别写成&p+i哦,这样子可是会挎了15个字节访问了哦。。。我们把代码修改下:

    #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 int main()
      5 {
      6         char *p = (char*)malloc(15);
      7         int i=0;
      8         memset(p,'A',15);
      9         for(;i<15;i++)
     10         {              
     11                  printf("p[%d]:%c ",i,p[i]);
     12         }
     13         printf(" ");
     14         
     15         strcpy(p,"zhongxiaoming");
     16         for(i=0;i<15;i++)
     17         {       
     18                 printf("p[%d]:%c ",i,p[i]);
     19         }
     20         printf(" ");
     21         free(p);
     22         p=NULL;
     23         return 0;
     24 }

    运行:

    Love-Yan:pointertest MD101$ make
    gcc -o malloctest malloctest.c -g
    Love-Yan:pointertest MD101$ ./malloctest
    p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:n p[12]:g p[13]: p[14]:
    Love-Yan:pointertest MD101$ 

    大功告成。。。

    不过,在这里,如果要考究下strcpy对p的15个字节处理了多少个呢?我们可以先用memset来对这15个字节进行下初始化,然后再输出看看就知道了。

    Love-Yan:pointertest MD101$ make
    gcc -o malloctest malloctest.c -g
    Love-Yan:pointertest MD101$ ./malloctest
    p[0]:A p[1]:A p[2]:A p[3]:A p[4]:A p[5]:A p[6]:A p[7]:A p[8]:A p[9]:A p[10]:A p[11]:Ap[12]:A p[13]:Ap[14]:A


    p[0]:z p[1]:h p[2]:o p[3]:n p[4]:g p[5]:x p[6]:i p[7]:a p[8]:o p[9]:m p[10]:i p[11]:np[12]:g p[13]:p[14]:A
    Love-Yan:pointertest MD101$ 

    good news。。。只是对前面的部分字节进行了赋值。可是第十四了也就是p[13]里边的内容是空的。。这是怎么回事?

    我们知道字符串的结尾是'‘对吧,里边会不会就是''呢?我们可以gdb一下。看看这个p[13]是什么。

    果然。。。

    (gdb) p p[13]
    $2 = 0 ''
    (gdb) 


  • 相关阅读:
    【今日CV 视觉论文速览】 19 Nov 2018
    【numpy求和】numpy.sum()求和
    【今日CV 视觉论文速览】16 Nov 2018
    【今日CV 视觉论文速览】15 Nov 2018
    poj 2454 Jersey Politics 随机化
    poj 3318 Matrix Multiplication 随机化算法
    hdu 3400 Line belt 三分法
    poj 3301 Texas Trip 三分法
    poj 2976 Dropping tests 0/1分数规划
    poj 3440 Coin Toss 概率问题
  • 原文地址:https://www.cnblogs.com/iosDevZhong/p/4395242.html
Copyright © 2011-2022 走看看