关于std::string的使用问题

项目中涉及图片的加载以及存储,直接从一个二进制文件中通过偏移量读取图片的数据,然后把图片二进制数据维护在内存里,当初为了方便,而且征求老大的意见结果就直接使用std::string来维护这些图片的数据。总的来说就是fread文件数据到string::data(),然后在绘制的时候创建出位图句柄,最后再把string::data()二进制数据直接fwrite到文件。一开始各种测试好像没问题,而且老大也说以前都是这么做的并没有发现什么问题。

然而我心中总觉得这么做似乎有些不妥。

首先拷贝构造,拷贝赋值。std::string必然实现的是深拷贝,重新分配内存然后拷贝所有数据,在性能上肯定有些问题。然而有大神却跟我说他在其它书上了解过,如果某个string的内容没有被修改过,那么它赋值操作只是浅拷贝,只有在修改内容时才会重新分配属于自己的内存。所有由于时间紧任务急,这时候就没有再计较这个问题(其实当时也怪自己没有实测一下,写个简单的测试例子多快,想想真没有技术品质)。

然后就是string的内存分配会不会存在问题,如果大的图片文件,用string来维护有没有问题。

终于代码写好,交付测试,才过几天老大接到crash。前两天没有dump文件,他自己一直在找这个crash,怀疑这里揣测那里,都没有什么进展。第三天dump文件出来了,一调试才知道是图片的问题

代码里用到std::map去保存那个图片的string,怎么看代码好像都没问题,又是写日志再确认一遍,终于日志出来了,确定确实是std::map的insert这张图片的string崩溃,日志反映出这种图片的大小是6M多文件名也有了,麻蛋,直接找当事人要过来文件,使劲草几遍果然就崩溃了,下面就能看见完整的堆栈了。

直接可以看出来insert操作对string进行过深拷贝,而且是深拷贝分配内存出错。打开资源管理器一看,占用内存1个多G。我的天,要命了,事实证明实践才是真理。

改掉代码,不再用map来insert,但还是用string来做图片数据管理,再次死草这张图片,又崩了!还是崩溃在拷贝赋值时分配内存失败。事实证明用string来存储这种资源问题的二进制数据是个天大的错误,每赋值一遍就会重新分配6MB的内存,每做一次传参就要拷贝一遍,性能就不说了,内存直接爆了。

所以大家以后在存储数据的时候千万不要想当然的把大文件以string的形式去维护,当然你如果能保证不使用拷贝赋值或拷贝构造另当别论。

这个问题也告诉自己,做技术要精益求精,认真对待每个细节,不能盲从,不要因为任务紧急就不去周全的考虑方案的各个细节问题,否则总有一天会付出相应的代价。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值