memmove(),memcopy(),memset()对std::string的影响。

2017-01-12 09:52:50来源:作者:CSDN博客人点击

memmove(),memcopy(),memset()是c语言中非常常用的函数,具体功能这里不详细介绍。当它们对于c++标准库中的string进行操作时会产生什么影响呢?我们先来看一段程序。

结果可以分为三个部分执行memmove前,执行后,以及改变数组第一个元素后(以*线隔开),我们可以看到执行memmove后跟我预期的一样,数组第一个元素变成和执行memmove前的第二个元素元素一样。但是把第一个元素说改变之后,奇怪的现象发生了,数组第二个元素也跟着变了。为什么呢?(这里推荐一篇文章:http://blog.csdn.net/passion_wu128/article/details/38353959),这和c++ string的内部实现原理有关,详细内容看此处的文章介绍,不再叙述。因为c++string 内部有一个缓冲区和指针,指针指向字符串的内存空间,当我们进行memmove操作时,它只对指针本身进行了copy也就是我们常说的浅copy,copy之后数组前两个元素的string指针指向了同一块内存区,因此我们改变其中一个,另外一个也跟着改变了。除此之外还有一个更严重的问题,我们看到程序在调用最后一个析构函数时挂掉了,这是我们最不愿意看到的。因为两个指针指向了同一块内存,在析构函数中释放了两次,因此在第二次调用析构函数释放了一块已经被释放的内存区,因此久挂了。

在文章中我们可以看到,c++ string其实是有一个缓冲区的,当字符串的长度没有超过缓冲区的长度时,是不会进行额外的内存空间的申请的,也就是说string具体内容,不是由string 内部的指针来决定的。为了验证我们把key的长度变短一点来看看会有什么结果。代码不再展示:,直接看结果

我们可以看到程序的每一部都跟预期的一样,memmove之后并没有因为一个的改变影响另外一个元素,这是为什呢。原因就在于我们字符串的长度没有超过缓冲区的长度,string并没有申请额外的地址空间,字符串保存在自己本身的缓冲区内,当我们进行memmove时把缓冲区也copy过去了,两个元素之间没有任何关联。

我们可以明显的意识到,当我们使用这些内存操作函数时,一定要注意指针的存在,当我们的struct或者class中有指针时一定要小心,不能使用这些函数去操作,我们通过这些函数只能操作指针本身,而指针指向的内存空间我们并没有去管理,因此就会造成各种bug,比如上面的崩溃,和数据错误,当我们使用memset还会导致内存泄漏(销毁指针前,内存空间没有释放)。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台