This topic has been archived. It cannot be replied.
-
工作学习 / 学科技术 / 有没有C++高手?请教个问题,先谢谢了。
-newrover(漫游);
2022-2-17
{723}
(#14379162@0)
+1
-
不是高手,写过几年C++。理论上你的做法合理,shared_ptr 自己释放内存,虽然我没用过,以前为了避免内存泄漏我的原则是谁创建的对象,谁负责释放内存,也就是对象在函数外产生,把指针或作为引用传递给函数
-vicky2005(孩子她爹);
2022-2-17
(#14379209@0)
-
对。使用智能指针的好处,就是基本上不用管堆上对象的释放了。我的理解是,在函数返回的时候,返回对象的引用,于是shared_ptr 的引用+1,局部的shared_ptr失效,引用-1.还是只有一个引用。外层函数退出的时候,外层的引用失效,内存被系统自动收回。
-newrover(漫游);
2022-2-17
(#14379236@0)
+1
-
在函数返回的时候,返回对象,返回引用不会引起reference count + 1,再说稍微好点的编译器会警告的
-suancaifentiao(suancaifentiao);
2022-5-19
(#14573561@0)
-
C++ 11里有move constructor,classA(classA&&)就是让你实现这种目的的。返回的是moved copy
-gta_palace(呄 - 每天乃古);
2022-2-17
(#14379244@0)
-
好的,我研究一下,好像见过这个&&,没研究过。谢谢。老大,还请问一下,我实现的方式是否合理?
-newrover(漫游);
2022-2-17
(#14379253@0)
-
现在编程不应该考虑内存大小问题,都64bit了,
-googlebot(bot);
2022-2-17
(#14379252@0)
-
还是要考虑的。最终程序在Vxworks上运行。据说Vx堆栈最大只能设到1M。搞大矩阵计算很容易溢出。关键Vxworks的release版还不检查堆栈溢出,程序可能已经崩溃了,用户还不知道。我是在Windows里的debug版调试的时候发现这个问题的。
-newrover(漫游);
2022-2-17
(#14379261@0)
-
没听过“内存泄漏”?
-vicky2005(孩子她爹);
2022-2-17
(#14379267@0)
-
嗯。要是泄露了。多少内存都不够用啊😂
-newrover(漫游);
2022-2-17
(#14379274@0)
-
现在的Java程序员都不知道这些
-vicky2005(孩子她爹);
2022-2-17
(#14379281@0)
-
他们好幸福🤣🤣
-newrover(漫游);
2022-2-17
(#14379291@0)
-
现在的初级Java程序员都不知道这些
-geekcode(文心雕码);
2022-2-17
(#14379624@0)
-
高级Java程序员也需要考虑内存泄漏的事情吗?Java没有内存泄漏的可能吧?
-newrover(漫游);
2022-2-17
(#14379652@0)
-
当然有。java leak后memory耗尽吗,查起来还很麻烦
-gta_palace(呄 - 每天乃古);
2022-2-17
(#14379667@0)
-
我对Java一窍不通,纯好奇。Java的堆内存不都操作系统统一管理了吗,也有leak的可能吗?我只听说Java可能有的时候因为管理内存的原因速度慢,有点卡
-newrover(漫游);
2022-2-17
(#14379672@0)
-
Java的heap是JVM管理,不是OS管理。leak通常是由于静态变量造成的。内存管理造成的速度慢可以选适合的GC。
-geekcode(文心雕码);
2022-2-17
(#14379696@0)
-
对了,Java运行在虚拟机上。慢是听一个前同事说的,他们的手术机器人要切人的。结果控制系统用java写,运行在Windows上,担心实时性不好。我们是C++运行在Vxwork上,倒是没有实时性的问题。
-newrover(漫游);
2022-2-17
(#14380483@0)
-
不太懂中文术语,内存泄漏是指memory leaking吧?记得Java 的设计初衷之一就是淘汰pointer 使用以避免不当使用造成memory leaking,所以搞出个garbage collector thread。Java 其他memory leaking 不可能吧?请教其详
-zbeifly(苇子坑);
2022-2-17
(#14379694@0)
-
参见
-geekcode(文心雕码);
2022-2-17
(#14379698@0)
-
谢谢,学习了。
-zbeifly(苇子坑);
2022-2-17
(#14379820@0)
-
太落伍,大部分c++编译器都有全局垃圾回收,自己释放内存已经是很古老的想法了,
-googlebot(bot);
2022-2-17
(#14380328@0)
-
你的意思是用智能指针?
-newrover(漫游);
2022-2-17
(#14380479@0)
-
现代编译器clang,g++都有垃圾回收,有个编译开关,
-googlebot(bot);
2022-2-18
(#14381014@0)
-
谢谢,学习了。
-newrover(漫游);
2022-2-18
(#14381019@0)
-
现在用c/c++的不多了,最大的开源项目是chromium,各个大公司积极为chromium提交代码,chromium里有400多开源项目,2000万行代码,
-googlebot(bot);
2022-2-18
(#14381054@0)
-
我们代码跟设备打交道,对实时性要求比较高,还用C++。连我们的架构师都说C++这种语言该消失了。🤣🤣唉,路越走越窄呀。人家刚毕业的小青年去大厂当厂哥,上来就拿20万。
-newrover(漫游);
2022-2-18
(#14381112@0)
-
确实落伍,我写 C++都是十几年前的事了
-vicky2005(孩子她爹);
2022-2-18
(#14381122@0)
-
用动态数组或集合,类似std::array / std::set(在主程序里建,函数调用时以Reference传入即可)。 使用Reference Count 的 +1 / -1 来控制何时释放内存的方法现在不太用了。
-flycloudy(ag);
2022-2-17
(#14380257@0)
-
谢谢。如果能用引用传进来就简单了。主要是为了代码看起来不是那么冗长,要在函数内部创建,然后返回直接放到计算公式中去。这就麻烦一点。
-newrover(漫游);
2022-2-17
(#14380478@0)
-
”函数内部创建“ --- 你这种方法是”埋地雷“,容易引进BUG。只要逻辑条例正确,”冗长“是没问题的。最怕的是一些小技巧Trick,为将来埋了地雷。
-flycloudy(ag);
2022-2-18
(#14380900@0)
+1
-
老兄说的有道理。主要我这里是一个矩阵求伪逆的函数,里面的公式就是几个矩阵相乘相加,取反。本来公式挺简洁,要是把每一步矩阵运算都分解,看着实在太惨。
-newrover(漫游);
2022-2-18
(#14380996@0)
-
”矩阵相乘相加,取反“ --- 这些运算函数都是定长的数据,哪来的要求使用动态数组的事情,把一个简单的事情复杂化了,
-flycloudy(ag);
2022-2-18
(#14381460@0)
-
确实定长,但是数据太大,栈放不下,所以才有不得不在堆上创建的苦衷。栈要是搞定了,哪需要这么费劲?这个库别人编写的时候,没考虑大矩阵运算的问题。他们算3X3当然没问题。我算45X9的时候,堆栈溢出了。
-newrover(漫游);
2022-2-18
(#14381474@0)
-
既然是堆.把指针传来传去就好了.smart pointer没优势.但也可用.你仔细查手册.有些细节可帮你.但atomic operation极大影响性能.但你不在乎
-somepeople(不要PM我,就不改);
2022-2-18
(#14381606@0)
-
这部分没有实时性要求。主要是受堆栈容量的限制了。老兄,赶脚你说的有点问题:智能指针经常操作堆内存呐。本来也是为了堆内存的正确释放,才发明了智能指针。
-newrover(漫游);
2022-2-18
(#14381712@0)
-
你正在把智能指针当普通指针用.所以我说你没事找事.另外,堆和堆栈你要清楚.(似乎你是知道的).一个正常计算机的堆栈能放下你的那个数组.估计你放在了第n个线程上了(n>1)
-somepeople(不要PM我,就不改);
2022-2-18
(#14381952@0)
-
Heap和stack我当然清楚。😂😂我的理解:有了智能指针,裸指针应尽量避免使用。关于堆内存分配的问题,正是需要智能指针的地方。不是线程的问题。是矩阵太大,函数嵌套也比较多。各线程应该有自己的堆栈吧?correct me if I am wrong
-newrover(漫游);
2022-2-18
(#14381972@0)
-
是.大小不一呢
-somepeople(不要PM我,就不改);
2022-2-18
(#14381981@0)
-
我这里有个难处,就是堆栈最大只能设到1M。据说是Vxworks系统的限制。我们的代码可以在Windows下初步调试,然后Vxworks硬件上执行。Windows下我把堆栈设到2M的时候,一切正常。缺省的1M栈,就溢出了。实际上,在Vx上,也貌似正常滴运行了。还是觉得有可能有问题。至少在Windows下,如果1M堆栈能顺利运行,心里就有底了。
-newrover(漫游);
2022-2-18
{75}
(#14382037@0)
-
Vxworks是bsd Unix. Posix标准的话是堆栈大小可调的
-somepeople(不要PM我,就不改);
2022-2-18
(#14382190@0)
-
这个我还真不清楚,我们的架构师说堆栈设为1M,已经最大了。没研究过Vxworks,赶脚是Unix like的
-newrover(漫游);
2022-2-18
(#14382261@0)
-
我二十多年前用过vxworks.与此话题无关
-somepeople(不要PM我,就不改);
2022-2-18
(#14382496@0)
-
我QNX还研究过1,2。Vxworks完全没研究过。
-newrover(漫游);
2022-2-20
(#14386961@0)
-
按你的描述: 你的一个函数 “算3X3当然没问题。我算45X9的时候,堆栈溢出了“, 按理说矩阵的”相乘相加,取反“,这类函数应该是有一个或两个INOPUT矩阵,和一个放结果的OUTPUT矩阵,这三者都是已安排的存储单元, 计算时也用不到大量临时变量, 怎么会有堆栈溢出的事情发生。我猜:该不是在这个函数中为放结果的OUTPUT矩阵去申请单元,那就是这个函数设计的败笔和漏洞。
-flycloudy(ag);
2022-2-18
{301}
(#14381899@0)
-
我没说清楚,我是说,算3X3的矩阵求逆,当然没问题,里面用到的转置,求逆函数都是直接返回矩阵对象,值传递,有大量的临时对象。矩阵规模小没问题。我算45X9的矩阵,就扛不住了。
-newrover(漫游);
2022-2-18
(#14381921@0)
-
这个矩阵求反是不是用了cramer方法使用了recursion?太大矩阵肯定爆stack,如果用LU分解法理论上不会爆栈的。
-zhengy4(_);
2022-2-18
(#14382201@0)
-
伪逆,没用递归。主要就是维数太大。
-newrover(漫游);
2022-2-18
(#14382254@0)
-
你如果是函数内产生的shared_ptr则在函数退出的时候会把shared_ptr做清除的。除非你有counter>1,你返回reference会得到一个已被回收的错误的东西,到时候无效内存区域引用就是seg fault,不明白为什么要这样做?shared_ptr一般都是返回shared_ptr让counter++的.
-zhengy4(_);
2022-2-18
(#14381039@0)
-
谢谢。貌似你说的有道理,正常我应该返回shared_ptr,外面也用一个shared_ptr来接收,然后在取值,这样就不会发生错误。或者干脆像飞云老兄说的,就在外层的函数里在堆上创建,然后,作为引用参数送进来,这样就可以返回引用了。即便公式看起来冗长一些,但不会出错。
-newrover(漫游);
2022-2-18
(#14381091@0)
-
在函数内创建shared_ptr是不好的行为啊,你真的要传递引用那也是要在函数之前创建shared_ptr,然后函数结束后用引用传递给下一步,并且要确保"下一步“是简单的,且从shared_ptr创建到引用结束是atomic的,否则一旦出现循环引用,和racing condition等状态就是埋雷。
-zhengy4(_);
2022-2-18
(#14381140@0)
-
貌似你说的有理。我这里到没有多线程的问题,这些步骤应该都是atomic操作。还问个问题,这里如果我用unique_ptr创建,然后把引用送到函数里,这样做合理吗?
-newrover(漫游);
2022-2-18
(#14381161@0)
-
用smart pointer传出来的话应该用std::unqiue_ptr,除非还要继续传。std::shared_ptr reference_count在这里是无用供,而且还要调用mutex系统call
-gta_palace(呄 - 每天乃古);
2022-2-18
(#14381383@0)
-
看来老兄是高手,正好请教:如果我在函数内用unique_ptr 在堆上创建资源,然后函数返回unique_ptr指针。函数外面也用unique_ptr接收,不继续传了。但这样不是用两个unique_ptr指向同一对象吗?不正是unique_ptr想避免的现象吗?可以这样用吗?
-newrover(漫游);
2022-2-18
(#14381467@0)
-
老实说.你似乎不太懂.你上面那个也不太懂.还是用最古老的方法吧
-somepeople(不要PM我,就不改);
2022-2-18
(#14381593@0)
-
不懂才要学习啊。
-newrover(漫游);
2022-2-18
(#14381679@0)
-
你打算下一步怎么学呢?
-somepeople(不要PM我,就不改);
2022-2-18
(#14381695@0)
-
先把C++ primer, efftive C++捋一遍。争取先入门。你有啥好建议没?
-newrover(漫游);
2022-2-18
(#14381704@0)
-
我这人很自私.不会平白无故地教人的.你这两本书感觉太低级了.话说我刚才给了你一个20万potential的面试:)一起努力.我的单位中.好同事一般都是小问题尽量自己努力的.你这个话题好,但是属于可以自己努力的部分
-somepeople(不要PM我,就不改);
2022-2-18
{85}
(#14381721@0)
-
我这不还没入门呐嘛。自己琢磨不明白就来问呗。。。虽然不会有20万的potential,学而常习之,不亦乐乎?这两天也给人面试呐,发现国内好多号称架构师的人,还不如我呐。🤣🤣有一个带团队在第一线的,声称C++1X从来没接触过。。。雁过拔毛,有啥高级一点的书推荐没?
-newrover(漫游);
2022-2-18
(#14381744@0)
-
我都十多年没有再碰c++了。:P
-zhengy4(_);
2022-2-18
(#14382101@0)
+1
-
哈哈哈,我来加拿大应聘过C++程序猿工作,被俄罗斯正牌码农鉴定为纯忽悠,然后OWNER出来,给offer了一个销售职位
-eleclan(eleclan);
2022-5-13
(#14562249@0)
-
你对std::unique_ptr理解不对,unique_ptr只能move,不能assign,不会出现两个变量指向同一个指针的情况
-gta_palace(呄 - 每天乃古);
2022-2-18
(#14381615@0)
-
确实,这部分以前也没用过。就是说只要不是assign。在函数里面和外面,可以用不同的unique_ptr指向同一个资源?然后在外面unique_ptr失效的时候,资源被自动回收?
-newrover(漫游);
2022-2-18
(#14381688@0)
-
因为你对move,rval没概念,这些是c++11后才有的。这贴子上很多人都是不懂装懂,与起被这些回复误导,还不如看看网页
-gta_palace(呄 - 每天乃古);
2022-2-18
{229}
(#14381828@0)
-
Move constructor 确实没接触过。Rval是右值吧?
-newrover(漫游);
2022-2-18
(#14381859@0)
+1
-
别生气,不一定不懂.太费神
Cpp reference我看着也费劲.对他而言不一定看得懂
-somepeople(不要PM我,就不改);
2022-2-18
{48}
(#14381957@0)
-
我不懂,他该高兴😊才对。有啥好生气的?😂😂😂
-newrover(漫游);
2022-2-18
(#14381977@0)
-
如果用unique_ptr, move后原先ptr就失效了,除非你在func里面return还是用move出来。
-zhengy4(_);
2022-2-18
(#14382351@0)
-
对
-somepeople(不要PM我,就不改);
2022-2-18
(#14382500@0)
-
你说的有道理。貌似如果我直接return这个unique_ptr,实际上编译器编译的时候,也是编译成move出来。
-newrover(漫游);
2022-2-20
(#14386936@0)
-
shared_ptr好像不能move成unique_ptr吧。楼主他在函数内做了shared_ptr的,除非他在函数内做unique_ptr然后move出来才行。
-zhengy4(_);
2022-2-18
(#14382220@0)
-
真
咱同事水平就是肉联高端
-somepeople(不要PM我,就不改);
2022-2-18
{24}
(#14381594@0)
-
十多年没有再碰c++了不要刚我,以前shared,weak互相使用可溜了。
-zhengy4(_);
2022-2-18
(#14382113@0)
-
老大,shared,weak出来也就十年多一点。你当初学的快呀。
-newrover(漫游);
2022-2-20
(#14386940@0)
-
从功能上你可以这么干.性能有可能会受影响.看编译器能不能优化了.否则有可能会产生copy的动作.C十十这方面规则太复杂了.也有move的.要仔细查Bye
-somepeople(不要PM我,就不改);
2022-2-18
{3}
(#14381583@0)
-
就是为了避免copy才这么做。可以copy我就不费那劲了。
-newrover(漫游);
2022-2-18
(#14381696@0)
-
根据很久以前(智能指针不流行的时候)的原则,谁construct object, 谁destruct它。 所以想当年我一般都是你说的那种:在函数外创建,用引用给函数,然后在函数外删除。
-moonhalf(石室矢士);
2022-2-18
(#14381809@0)
-
这样做确实比较规范。问题是,现在编程,总会有些负责创建资源的类吧?否则,什么都要自己创建,岂不是很麻烦?有这样的类,就会有类内创建,类外删除的需求。楼上说的move constructor可能就是答案。
-newrover(漫游);
2022-2-18
(#14381855@0)
-
对。C++最近进化很频繁。应该有更好的解决方案
-moonhalf(石室矢士);
2022-2-18
(#14382555@0)
-
搞到现在,我才了解到楼主的问题是:调用一个已存在的函数计算大尺寸矩阵的逆矩阵(例如45X9),结果这个函数由于堆栈溢出而Crash了,问:如何在最大堆栈只能设到1M条件下解决这个问题? 这样讲是不是比楼主讲的更清楚些?
-flycloudy(ag);
2022-2-18
(#14381976@0)
-
高人哪。你咋一下就说清楚了聂?服了。👍👍👍谢谢😂😂。补充一下,这个函数内部调用求转置,方阵求逆函数,都是直接返回矩阵对象。造成大量栈内存的占用。
-newrover(漫游);
2022-2-18
(#14381979@0)
-
是不是可以就简单返回裸指针?由调用函数决定如何使用返回的指针。
-cricketkiller(白牙青);
2022-2-18
(#14382105@0)
-
当然可以,没有智能指针的时候,都是这么用的。我的理解,有了智能指针,尽量避免使用裸指针。
-newrover(漫游);
2022-2-18
(#14382249@0)
-
函数返回的裸指针马上赋值给一个智能指针,这样灵活性比返回智能指针大一点,也可以省去研究 move constructor 了。
-cricketkiller(白牙青);
2022-2-18
(#14382295@0)
-
这种方法应该可行,我还是不大愿意裸指针和智能指针混用。最后还是用了unique_ptr。正好把move也搞清楚了。
-newrover(漫游);
2022-2-20
(#14386358@0)
-
不会C++, 但是觉得"对象在函数外生成,并作为引用输入参数传递给函数"比较常见,而且符合你的要求。
-piglet(小猪);
2022-2-18
(#14382320@0)
-
按照ARAII的原则,确实应该尽量如你所说。但我觉得总可以设计一些类或者方法,专门用来分配资源,这样返回指针应该也是合理的。
-newrover(漫游);
2022-2-20
(#14386366@0)
-
C和C++的总原则,function的参数碰到structure,一律用指针。
-haploidus(今剩叹);
2022-2-18
(#14382531@0)
-
C可能是这样。C++用引用应该也可以。
-newrover(漫游);
2022-2-20
(#14386368@0)
-
哥们要是还在用C++,建议转Unreal游戏编程吧;游戏做好了,是仅次于毒品军火的挣钱买卖
-binghongcha76(一只大猫);
2022-2-18
(#14383314@0)
-
Unreal是指什么?虚拟现实游戏吗?以前倒是有个游戏叫Unreal。
-newrover(漫游);
2022-2-20
(#14386370@0)
-
是游戏引擎啊,最早的Unreal游戏就是这款引擎做的,市场上大部分3A 3D大作都是Unreal引擎开发的
-binghongcha76(一只大猫);
2022-2-21
(#14388927@0)
-
学习了,谢谢。当吃Unreal游戏好像做的挺牛的。我就玩了一点点。那个 half life 引擎不好吗?后来反恐精英不是用自己的引擎吗?
-newrover(漫游);
2022-2-21
(#14389211@0)
-
unreal是通用引擎,不过好多大的游戏公司使用自己的游戏引擎,比如Far Cry 系列,用Crytek引擎;微软最新的的帝国时代也用的定制的特殊引擎
-binghongcha76(一只大猫);
2022-2-23
(#14393853@0)
-
明白了,谢谢。我不是靠C++吃饭,但编程也只会C++。还在入门级水平挣扎涅。游戏引擎估计我学起来有难度,什么纹理,渲染,我一窍不通啊。😂😂
-newrover(漫游);
2022-2-23
(#14393894@0)
-
汇报一下情况:根据大家的指导,把求伪逆函数内部用到的求转置,单位阵求逆能函数,内部在堆上产生的矩阵用unique_ptr去指。返回类型也是unique_ptr。
-newrover(漫游);
2022-2-20
{524}
(#14386427@0)
-
最后来汇报一下进展,搞定了。读了一下重载的矩阵相乘操作符:* 和 *= 的代码。发现他们都调用了有个底层函数Mutiply,这个函数接收相乘矩阵,以及相乘结果的引用为参数,正好是我需要的。我可以在函数外的堆上先生成结果矩阵。
-newrover(漫游);
2022-2-20
{553}
(#14386923@0)
-
最后再更新一下。跟我们的架构师讨论了一下,他也觉得函数返回unique_ptr的举动不靠谱,虽然暂时正常工作,总觉得危险。于是从善如流,改成了函数外,堆上生成对象,然后用reference送到函数里处理的方法。与本坛大佬们的建议相同,这样也符合RAII的原则。再次感谢各位!
-newrover(漫游);
2022-2-23
(#14393815@0)
+1
-
don't return ref to a local shared_ptr obj, return the object itself. the object is small, and there are all kind of optimization in release version, almost no performance compromise.
-suancaifentiao(suancaifentiao);
2022-5-12
(#14559139@0)
-
老大,就是因为要用到大矩阵做局部变量,才造成堆栈溢出。另外,返回大矩阵也不大合适
-newrover(漫游);
2022-5-13
(#14562225@0)
-
大个的obj 不适合放在栈上, shared_ptr<> obj 很小,没问题
{
std::shared_ptr<BIG_MATRIX> obj = std::make_shared<BIG_MATRIX>( your params to construct BIG_MATRIX);
... do your work
return obj;
}
-suancaifentiao(suancaifentiao);
2022-5-19
{379}
(#14573520@0)
-
给加个一👍我不是高手,但我的做法就是你搜到的,“对象在函数外生成,并作为引用输入参数传递给函数”,道理很简单,谁的屁股谁负责擦,销毁和生成要在同一个地方,要么都在函数内部,要么都在函数外部。我这个做法,当年其他程序员和项目经理都是认可的
-eleclan(eleclan);
2022-5-13
{46}
(#14562241@0)
-
shared_ptr 说:尽管造吧, use it and forget it, 我负责擦屁股
-suancaifentiao(suancaifentiao);
2022-5-19
(#14573593@0)