【问题标题】:C++ unexpected change of members dataC++ 成员数据的意外更改
【发布时间】:2016-02-05 20:32:10
【问题描述】:

我的一个班级有一个问题:它的成员数据可能会意外更改。

我已经阅读了关于 SO 的类似主题,并且对于 未定义的行为指针 的问题似乎很明显。但即使我的代码很容易表达,我仍然拥有它:

aid.cpp:

#include "aid.h"

bool AID::Detect(t_arr3d x, t_arr3d x_p1, t_arr3d x_p2, t_arr3d x_p3, t_arr3d x_p4, int fp) {
    return false;
}

AID::AID() {
    this->counter = 0;
    maxErrorBound = 0.1;
    maxErrorBound2 = 0.02; // = maxErrorBound * lambda
}

aid.h

#ifndef AID_H_
#define AID_H_

#include "detector.h"
#include "vec.h"
#include <map>
#include <vector>
#include <limits>
#include <cstddef>
#include <boost/assign/list_of.hpp>
#include <boost/unordered_map.hpp>
#include "constants.h"
using namespace rode;
using boost::assign::map_list_of;
using namespace std;


class AID: public Detector {

public:
    bool Detect(t_arr3d x, t_arr3d x_p1, t_arr3d x_p2, t_arr3d x_p3, t_arr3d x_p4, int fp);

    AID();

private:
    int counter;
    float maxErrorBound  ;
    float maxErrorBound2; 
};
#endif

该类在另一个(rode.cpp)中被调用:

...
if(a_detector == "AID"){
    AID d = AID( );
    this->aid = &d;
} 
...

对于 LLDB,我设置了一个观察点来检查发生了什么:

Watchpoint 1 hit:
old value: 0
new value: 1606405696
Process 38408 stopped
* thread #1: tid = 0x74cd2, 0x00007fff5fc12171 dyld`ImageLoaderMachO::findExportedSymbol(char const*, bool, ImageLoader const**) const + 13, queue = 'com.apple.main-thread', stop reason = watchpoint 1
    frame #0: 0x00007fff5fc12171 dyld`ImageLoaderMachO::findExportedSymbol(char const*, bool, ImageLoader const**) const + 13
dyld`ImageLoaderMachO::findExportedSymbol:
->  0x7fff5fc12171 <+13>: pushq  %rax
    0x7fff5fc12172 <+14>: movq   %rcx, %r14
    0x7fff5fc12175 <+17>: movl   %edx, -0x2c(%rbp)
    0x7fff5fc12178 <+20>: movq   %rsi, %r15
(lldb) bt
* thread #1: tid = 0x74cd2, 0x00007fff5fc12171 dyld`ImageLoaderMachO::findExportedSymbol(char const*, bool, ImageLoader const**) const + 13, queue = 'com.apple.main-thread', stop reason = watchpoint 1
  * frame #0: 0x00007fff5fc12171 dyld`ImageLoaderMachO::findExportedSymbol(char const*, bool, ImageLoader const**) const + 13
    frame #1: 0x00007fff5fc184f6 dyld`ImageLoaderMachOCompressed::resolveTwolevel(ImageLoader::LinkContext const&, ImageLoader const*, bool, char const*, bool, ImageLoader const**) + 86
    frame #2: 0x00007fff5fc18784 dyld`ImageLoaderMachOCompressed::resolve(ImageLoader::LinkContext const&, char const*, unsigned char, long, ImageLoader const**, ImageLoaderMachOCompressed::LastLookup*, bool) + 276
    frame #3: 0x00007fff5fc1a09b dyld`ImageLoaderMachOCompressed::doBindFastLazySymbol(unsigned int, ImageLoader::LinkContext const&, void (*)(), void (*)()) + 235
    frame #4: 0x00007fff5fc0424e dyld`dyld::fastBindLazySymbol(ImageLoader**, unsigned long) + 90
    frame #5: 0x00007fff9610b3ba libdyld.dylib`dyld_stub_binder + 282
    frame #6: 0x000000010004f268 wrf2sl`GCC_except_table678 + 3660
    frame #7: 0x00000001000270f9 wrf2sl`main(argc=15, argv=0x00007fff5fbffaa0) + 21337 at wrf2sl.cc:170
    frame #8: 0x00007fff9610d5c9 libdyld.dylib`start + 1

wrf2sl 是我的程序。但其余的与它无关。

你见过类似的麻烦吗? 我应该如何检查以了解发生了什么?

【问题讨论】:

  • 提取一个最小的例子。我的猜测:违反了三定律或一些悬空指针。
  • this-&gt;aid = &amp;d; 绝对是个问题。我很惊讶它可以在您发布的小代码中找到。
  • 为什么我被否决了?我的问题有什么不正确的地方?

标签: c++ class lldb


【解决方案1】:

问题来了

if(a_detector == "AID"){
    AID d = AID( );
    this->aid = &d;
} 

在这里,您在if 主体的范围内创建了一个局部变量,它仅在内部是局部的。然后存储一个指向该局部变量的指针,一个指向在if 语句完成后被破坏的对象的指针。当您尝试取消引用指向不存在对象的指针时,这将导致未定义的行为

我的建议是不要使用指针开始,而是将对象存储为一个值(即AID 类的实际实例)。如果您必须使用指针,则使用new 动态分配它,并在完成后记住delete(或根据用例选择使用smart pointer) .

【讨论】:

  • 是的,您节省了我的时间,非常感谢。很好的解释。只是为了确定:我不需要删除它,如果课程保持到程序结束?
  • @pl-94 你应该养成一个好习惯,在你new 的所有事情上总是做delete,即使生命周期应该是直到程序结束(但是那么我根本不认为需要使用指针)。
  • 确实在这里指针是没用的。但我没有得到实际的区别。为什么要删除指针而不删除值?
  • @pl-94 “值”(或者更确切地说是对象实例)在超出范围或对象包含在另一个对象中时自动销毁和取消分配容器超出范围(等)。如果您动态分配或创建某些东西,它永远不会超出范围,您必须显式取消分配或销毁该对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
相关资源
最近更新 更多