C++ 成员数据的意外更改

C++ unexpected change of members data

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

我在 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

class在另一个(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 是我的程序。但其余的与它无关。

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

问题就在这里

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

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

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