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).
我的一个 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).