首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当为实例变量(即对象)调用getter函数时,实际发生了什么?

当为实例变量(即对象)调用getter函数时,实际发生了什么?
EN

Stack Overflow用户
提问于 2013-12-05 19:37:45
回答 1查看 486关注 0票数 1

最近,我不断地与一个导致SEGFAULT随机函数的函数进行斗争。为了找出这个问题,我做了一些额外的工作之后,我想出了以下几点:

通过pastebin张贴的所有代码:

BUILD 1:这是原始代码,它会导致以下SEGFAULT (给定链接后) http://pastebin.com/huzcqnDA

SEGFAULT:

代码语言:javascript
复制
#0 6FC657AC libstdc++-6!_ZNKSs4_Rep12_M_is_leakedEv() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#1 6FC89FDB libstdc++-6!_ZNSs4_Rep7_M_grabERKSaIcES2_() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#2 6FC8C0E7 libstdc++-6!_ZNSsC1ERKSs() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#3 0094A470 Carp::Sprite::Sprite(this=0x27fae8, s=...) (Z:/CPP Programming/Carperon/Source/Carp/Engine/StructL2.hpp:28)
#4 00944E98 Carp::Item::_spr(this=0x1277eb80) (Z:/CPP Programming/Carperon/Source/Carp/../Carp/Classes.hpp:59)
#5 00416219 Carp::WinBag::update(this=0x2857f8, o=false) (Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp:60)
#6 00419304 Carp::GameUI::checkUpdate(this=0x2857e4) (Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp:240)
#7 00401B7D Carp::GameApp::loopGame(this=0x2801ac) (Z:\CPP Programming\Carperon\main.cpp:35)
#8 00402145 _fu2041___ZSt4cout() (Z:\CPP Programming\Carperon\Source\Application.cpp:25)
#9 004017A9 main() (Z:\CPP Programming\Carperon\main.cpp:6)

build 2:这是当前的构建,目前会导致编译器错误,这使我认为这可能是问题的原因。http://pastebin.com/89gCjH5P

错误:

代码语言:javascript
复制
Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp|57|error: no match for 'operator<<' in 'std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* & std::cout), ((const char*)"Item Info: ")))->std::basic_ostream<_CharT, _Traits>::operator<< <char, std::char_traits<char> >(a)), ((const char*)"\012ItemContainer: ")))->std::basic_ostream<_CharT, _Traits>::operator<< <char, std::char_traits<char> >(((const void*)((Carp::WinBag*)t|

当我调用Character中给出的getter函数时,实际发生了什么?我没有看到问题在这里是什么,而之前的Q&因为我发现不能解决这个问题,他们只会导致它破坏另一个随机函数。

最好的情况是Heisenbug,因为只有在程序中其他地方处于调试模式的情况下才会发生这种情况。

我发现的唯一可能的帮助是在我的getter中使用const-正确性,只是再次将相同的SEGFAULT带到板上(在编译过程中浪费时间)。

我的程序有与Ogre3D的静态链接,这使得我的平均编译时间为5分钟(如果我更改特定的标题,则超过7分钟)。因此,我需要很长时间才能发布编辑/结果。

P.S. Carp::WinBag与示例代码中给出的Carp::Interface相同(给出了错误的类名)

额外注意:我已经连续5天连续发生了这个问题。我的理智只能承受这么多.

解决方案:我的情况是由于代码中其他地方的懒惰造成的:

代码语言:javascript
复制
ItemPtr temp(new Item(*listItem[1].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);
temp.reset(new Item(*listItem[2].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);
temp.reset(new Item(*listItem[3].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);

这样,我创建了一个指向新对象的指针,但同时导致旧对象丢失(内存泄漏了吗?)。这导致了我以后在代码中遇到的所有问题,用正确的方式编写它将修复它。

我真不敢相信,这么长时间后我又这样做了,更糟糕的是,我没有意识到.对于任何不幸认为这是有效的其他人,请不要。它会给你带来无尽和混乱的压力:*

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-05 19:55:33

字符不能保证项已初始化为指针。当您调用它时,它只返回一个指针。如果该指针尚未初始化(或已初始化到错误的内存位置),尝试访问该指针可能会导致seg错误:

代码语言:javascript
复制
Character c;
Intem* items = c._items();//get uninitialized ptr in c
items[foo];//seg fault (maybe)

当然,这不是你在电话中得到故障的唯一方法。

在getter调用中实际发生的情况是,您正在接受一个"this“指针,将偏移量应用到"this”指针上,以查找"items“指针,并返回该值。但是,如果“此”指针无效,则可以得到一个seg错误。所以:

代码语言:javascript
复制
Character* c;//not inititialized
c->_items();//seg fault (maybe)

只能自己造成断层。

但是,seg错误并不总是发生:如果指针位置恰好是良好的内存,您将不会看到seg错误,您将继续进入未定义的行为模式。

那么你到底是如何调试这些东西的呢?必须承认,这是一个痛苦的屁股。这是人们不喜欢C和C++的主要原因之一,我不认为这里的大多数人会去找你。

调试模式下的大多数编译器将强制未初始化的指针指向值。有时值在六语中(我最喜欢的是0xBADF00D)。所以看看你的指针值。Visual初始化指向0xccccccccccccc的指针。

但是,避免这类问题的最佳方法是使未初始化的指针不可能出现。使用向量和参考。当您必须使用指针时,请坚持使用智能指针。在构造函数和析构函数中使用RAIIdesign模式。遵循3的规则(或c++11中的3-5规则).您将不会(好吧,您将“很少”)需要寻找无效的值,因为您已经使它们很难存在。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20409005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档