指向父级更改的指针无缘无故
pointer to parent changes for no reason
我有两个类像这样说A和B:
// A.h
#include <iostream>
#include <vector>
using namespace std;
#ifndef A_H_
#define A_H_
#include "B.h"
class A {
public:
std::vector<B> bVec;
A();
void foo();
virtual ~A();
};
#endif /* A_H_ */
//--------------------
// A.cpp
#include "A.h"
A::A() {
B b(this);
bVec.push_back(b);
}
void A::foo() {
for(int i=0; i<bVec.size(); i++)
bVec[i].addNewB();
}
A::~A() {
}
//--------------------
// B.h
#include <iostream>
#include <vector>
using namespace std;
#ifndef B_H_
#define B_H_
class A;
class B {
public:
A* parent;
double data[15];
B(A* p);
void addNewB();
virtual ~B();
};
#endif /* B_H_ */
//--------------------
// B.cpp
#include "B.h"
#include "A.h"
B::B(A* p) {
parent = p;
}
void B::addNewB() {
A* tmpA = parent;
if(parent->bVec.size() < 3)
{
std::cout<< "Before: " << parent->bVec.size() << 'n';
parent->bVec.push_back(B(parent));
std::cout<< "After: " << parent->bVec.size() << 'n';
}
if(tmpA == parent)
cout<< "parent the samen";
else
cout<< "parent changedn";
}
B::~B() {
}
//--------------------
// main.cpp
#include <stdio.h>
#include "A.h"
int main()
{
A a;
a.foo();
std::cout<< "finishn";
return 0;
}
当我运行此代码时,我得到以下结果:
之前:1
之后:16276538888567495168
父级已更改
之前:2
之后: 3
父级相同
父级相同
完成
如您所见,问题是有时父指针在push_back后会发生变化。我尝试在检查父指针之前和之后调试代码push_back。在此之前它是一些地址,但在那之后它是其他内容加上此文本:这似乎有一些分段错误。
这里问题的关键似乎是每个 B 实例的大小。如果我将"数据"的大小更改为低于 14 的大小,程序可以正常工作,但对于 14 或更高,就会发生这种情况。
这看起来很奇怪,我花了好几天的时间挣扎。你能告诉我为什么会这样吗?
void B::addNewB() {
A* tmpA = parent;
if(parent->bVec.size() < 3)
{
std::cout<< "Before: " << parent->bVec.size() << 'n';
parent->bVec.push_back(B(parent));
std::cout<< "After: " << parent->bVec.size() << 'n';
}
if(tmpA == parent)
cout<< "parent the samen";
else
cout<< "parent changedn";
}
bVec 在此处进行了更改,其中包含正在运行代码的特定B
对象的this
。
void A::foo() {
for(int i=0; i<bVec.size(); i++)
bVec[i].addNewB();
}
此调用中bVec
已更改。 在超过预分配堆空间的push_back()
调用(可能像这个)上,vector
需要重新分配堆内存并移动所有内容。 在移动过程中,vector
销毁了运行该代码的B
对象。 控制恢复到B
代码与过时的this
,因此this->parent
现在包含垃圾。
回溯可能是这样的:
A::foo()
B::addNewB()
vector<B>::reallocate() //destroys previous frame's B
一个向量分配的空间比size()
建议的要多,你可以找到
随着capacity()
而出,随着reserve()
而改变。这意味着,当
你push_back()
有成长的空间。当空间用完时,
整个向量重新分配更多空间,此过程移动现有
内存中的对象。这就是为什么你得到的指针指向
不再存在。
向量始终将其所有对象连续(按顺序)保存在内存中。
一种可能的解决方案是reserve
足够的空间,以便
重新分配永远不会发生,另一个切换到std::list
.
另请注意,不仅仅是您的父指针失效,因为你
正在从所述向量中对象的方法触发向量重新分配,
您还使用无效的this
指针。
我认为指针不会改变parent
。据我所知,错误在于,foo()
您在每次迭代中遍历bVec
调用size()
,而bVec
的大小在调用addNewB
后发生变化。
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 指向父级更改的指针无缘无故
- 指针工作,然后似乎无缘无故地中断