C++BUG小记——自己写的库都是雷
来源:互联网 发布:邮箱注册淘宝流程 编辑:程序博客网 时间:2024/05/22 00:35
BUG描述
环境
C++ 14Visual Studio 2017zMatrix
描述
zMatrix是我自己造的图像处理的轮子,这几天想着在上面实现一个3层的神经网络识别手写数字,完成之后进行适当的优化,问题出在这里。 _Matrix
作为库的基础,是用来存放图像的,期初没有考虑作为容器来存放任意类型。在实现nn过程中,需要用到序列容器,我用了vector
,但是vector并不能进行线性代数运算,但是_Matrix
是可以进行基础类型的运算的,所以我把_Matrix
适当修改,让它支持_Matrix
类型的运算,并且支持使用_Matrix
初始化
auto m = vector<vector<_Matrix<double>>>();// 改为auto m = _Matrix<_Matrix<_Matrix<double>>>(2, 1, 1, _Matrix<_Matrix<double>>(2, 1, 1))
起初我用Release模式跑的没有问题,准确率在90%以上,但是最后我用Debug模式跑的时候出问题了,不到10%。
问题出在对数据进行更新的时候,对m中的第一个数据读写没有问题,但是对第二个读写的时候就不对了,单步跟踪也没看出个所以然。
然后我就写了一个测试demo
default_random_engine random_engine(time(nullptr));uniform_real_distribution<double> real_distribution(-1.0, 1.0);// 使用随机数初始化auto www = _Matrix<_Matrix<_Matrix<double>>>(2, 1, 1, _Matrix<_Matrix<double>>(2, 1, 1, _Matrix<double>(2, 1, 1, make_pair(random_engine, real_distribution))));for(auto& ww : www) { for(auto & w: ww) { auto v = w; w = w - w; }}
如果有数据操作w = w - w;
里层第二遍读出的数据就不对了,如果没有数据操作就不会有问题。
我一直怀疑是数据操作过程中是不是有溢出之类的指针操作错误,但是发现操作过程和写入过程都没有问题。
为了定位到哪一步破坏了数据,修改demo
default_random_engine random_engine(time(nullptr)); uniform_real_distribution<double> real_distribution(-1.0, 1.0); auto www = _Matrix<_Matrix<_Matrix<double>>>(2, 1, 1, _Matrix<_Matrix<double>>(2, 1, 1, _Matrix<double>(2, 1, 1, make_pair(random_engine, real_distribution)))); auto& w11 = www.at(0).at(0); auto& w12 = www.at(0).at(1); auto& w21 = www.at(1).at(0); auto& w22 = www.at(1).at(1); for(auto& ww : www) { for(auto & w: ww) { auto v = w; w = w - w; } }
这样可以监听到每个数据在每一步运算过程中的变化。发现在运算过程中没有问题,数据错误发生在离开第一次循环进入第二次循环的时候。F**K.
调试了几遍之后,还是没有问题,然后我发现这样初始化容器中的数据是相同的,不太方便,我改成不同的数据方便查看。
auto www = _Matrix<_Matrix<_Matrix<double>>>(2, 1, 1, _Matrix<_Matrix<double>>(2, 1, 1)); auto& w11 = www.at(0).at(0) = _Matrix<double>(2, 1, 1, 0.1); auto& w12 = www.at(0).at(1) = _Matrix<double>(2, 1, 1, 0.2); auto& w21 = www.at(1).at(0) = _Matrix<double>(2, 1, 1, 0.3); auto& w22 = www.at(1).at(1) = _Matrix<double>(2, 1, 1, 0.4); for(auto& ww : www) { for(auto & w: ww) { auto v = w; w = w - w; } }
改为这样之后,更让我奇怪的事情出现了,为什么第三个和第一个数据相同,第四个和第二个数据相同?然后从赋值的地方初始化,发现,第三个赋值时,第一个数据同样被赋值了。查到地址,发现,两个数据的地址是相同的。
这下明确了,问题出在定义www初始化的时候。
最后发现,问题出在,_Matrix
类使用引用计数管理内存,拷贝为浅拷贝,用一个_Matrix
初始化一个容器,容器中的_Matrix
数据指向的内存是相同的一块。
Fix
针对_Matrix
进行特化。
- C++BUG小记——自己写的库都是雷
- 自己写的平面柱状图,有个小bug
- 自己写的bug,却死也调不出来
- [C#]写自己的类库
- C调用自己写的动态库
- 每个人都是自己的CEO—采访张潇清
- .Net正则的小记——都是粗心大意惹的祸
- C++-----自己写的哈希表
- 学了J2SE半个月,自己独立写的第一个小东西——计算器(bug待修复啊~)
- 自己写的一个链表,可能有bug
- 自己写的PAGE分页库配件(C#+javascript)
- lua学习实例,都是自己写的,慢慢摸索,涵盖了lua常用的方法
- 自己写的二分算法,网上大多都是有问题的
- 跟着别人做的一些数据库练习,答案都是自己写的,
- 自己用C写的单链表
- 自己用C写的通讯录
- [c#][测试]自己写的混淆代码
- 自己写的C语言简单万年历
- 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)
- SettingsActivty的监听状态变化
- Git使用-远程仓库
- 301重定向可促进搜索引擎优化效果
- python-识别中文路径
- C++BUG小记——自己写的库都是雷
- CRC-16 (Modbus)校验码
- 数据库复习总结(未写完...)
- e.target与e.currentTarget的区别
- /usr/bin/ld: cannot find -lxxx 问题解决
- Microsoft Edge真奇怪
- 【Linux】CentOS7安装Python3
- 阿里业务研发经典案例:另类解法,分布式一致性
- C#实现item自定义颜色的ListBox,显示日志