有如下一段代码,意图把“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\t",i,*(p+i));
 12         }
 13         printf("\n");
 14         free(p);
 15         p=NULL;
 16         printf("ok\n");
 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\t",i,p[i]);
 12         }
 13         printf("\n\n");
 14         
 15         strcpy(p,"zhongxiaoming");
 16         for(i=0;i<15;i++)
 17         {       
 18                 printf("p[%d]:%c\t",i,p[i]);
 19         }
 20         printf("\n");
 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]里边的内容是空的。。这是怎么回事?

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

果然。。。

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

转载于:https://www.cnblogs.com/iosDevZhong/p/4395242.html

关于malloc与字符指针的一些易错点相关推荐

  1. C语言指针的一些易错点

    指针 指针是一种数据类型,就像 int和 float,int 装整型数据,float 装浮点型数据,指针装地址型数据. C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或 ...

  2. 智能指针之shared_ptr易错点05

    一 shared_ptr易错点 1 慎用裸指针给shared_ptr赋值 例1 class A {public:A() {};A(int i) {m_i=i;cout<<"A&q ...

  3. c语言指针编程易错点,C语言中指针的一些易错点!

    1.字符数组与字符串的使用 注意:数组名是指向数组首个元素的地址. 先看个例子: #include int main() { char *str = "hello"; int le ...

  4. C语言内存管理-字符数组与字符指针

    堆和栈的区别 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 操作方式类似于数据结构中的栈. 2.堆区(h ...

  5. c语言结构体定义字符串数组,C语言,结构体中字符串的声明(采用字符指针还是字符数组)...

    结构体中,字符串选项是用字符数组表示好,还是用字符指针表示好? typedef struct person{ char *name; int age; char sex[6]; }: 该结构体中nam ...

  6. c语言指针易错情况,C语言/C++从入门到精通之指针易错点总结

    指针是C语言的灵魂,所以学好指针很关键,本篇主要介绍了C语言/C++从入门到精通之指针易错点总结,通过具体的内容向大家展现,希望对大家C语言/C++的学习有所帮助. 学习C语言肯定会碰到指针,指针是C ...

  7. 对使用字符指针变量和字符数组的讨论

    区别:1.字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址). 2.赋值方式.对字符数组只能对各个元素赋值,不能用以下方法对字符数组赋值:char ...

  8. 字符串,字符指针,字符串指针,字符数组

    对于指针可能是大多数程序员最痛苦的事,尤其是指针和字符串和数组三者放在一起的时候,经历了几次错误后,我打算总结一下这几者的区别. 字符串:"asdasfsff",c语言中后面有'\0'. 字符数组:A ...

  9. 《C语言杂记》C语言字符数组与字符指针(指向字符串的指针)详解

    C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,字符数组用法很简单我们还是来你看个例子吧. #include <stdio.h> #include <string ...

最新文章

  1. SAP CRM settype的创建,背后发生了什么
  2. 用户空间与内核空间数据交换的方式(1)------debugfs
  3. python获取程序文件中的全局变量和局部变量的函数
  4. Javascript组成--ECMAScript,DOM,BOM
  5. 李洪强iOS开发之Foundation框架—结构体
  6. javaweb中运用fileupload上传文件
  7. java string 去掉两边的引号_编写一个简单的java程序
  8. c#遍历匹配串口(向每个串口发数据,根据返回数据确定是否为所需串口)
  9. Linux串口调试工具
  10. mysql 易语言 邮件_易语言实现163邮箱登录获取邮件列表等操作的代码
  11. 王者荣耀背景html,《王者荣耀》登录界面背景怎么修改 登录背景图片更换方法...
  12. DTM测试里无线Modem应该选哪种MCU?
  13. 环签名原理与隐私保护
  14. (六)DDR协议功能之ODT模式与ZQ校准
  15. 蓝桥杯真题 - 费解的开关题解
  16. 模型评估之过拟合与欠拟合
  17. ld: library not found for -l.... 问题的解决
  18. 天锋w2019_天锋W2019竟然仿的这么像,这是要让三星气吐血吗?
  19. 英式音标26字母发音规律
  20. Python编程思想(24):类的实例方法

热门文章

  1. Onvif2.6.1命名空间前缀对照
  2. Webpack4干货分享(二),使用loader处理scss,图片以及转换JS
  3. 35.6. /etc/dnsmasq.d/dnsmasq.address.conf
  4. 【Ext.Net学习笔记】01:在ASP.NET WebForm中使用Ext.Net
  5. LintCode: Search A 2d Matrix
  6. Hibernate初学之CURD
  7. redhat oracle 开机自启动
  8. Silverlight 计时器
  9. android打印intent flag,Android flag详解
  10. 深度学习之卷积神经网络 AlexNet