我有以下课程:
Bar.hpp
#include <string>
class Bar
{
public:
Bar(const std::string& info);
std::string getInfo() { return info; }
protected:
private:
std::string info;
};
Bar.cpp:
#include <Bar.hpp>
Bar::Bar(const std::string& info)
: info(info) { }
Foo.hpp:
#include <string>
#include <vector>
#include <Bar.hpp>
class Foo
{
public:
static void printInfoStore();
static Foo* getFoo(const std::string& name);
Foo() {};
std::string getName() { return name; }
std::vector<Bar> getBars();
void addBar(const std::string& info);
protected:
private:
static std::vector<Foo> infoStore;
Foo(const std::string& name);
std::vector<Bar> bars{};
std::string name;
};
Foo.cpp
#include <iostream>
#include <Foo.hpp>
Foo::Foo(const std::string& name)
: name(name) { }
//static
std::vector<Foo> Foo::infoStore(0);
//static
void Foo::printInfoStore() {
std::cout << "InfoStore is { ";
for (Foo& foo : infoStore) {
std::cout << foo.getName() << "=[ ";
for (Bar& bar : foo.getBars()) {
std::cout << bar.getInfo() << " ";
}
std::cout << "] ";
}
std::cout << " }" << std::endl;
}
//static
Foo* Foo::getFoo(const std::string& name) {
for (Foo& foo : infoStore) {
if (foo.getName() == name) {
return &foo;
}
}
Foo* foo = new Foo(name);
infoStore.push_back(*foo);
return foo;
}
std::vector<Bar> Foo::getBars() {
return bars;
}
void Foo::addBar(const std::string& info) {
Bar* bar = new Bar(info);
bars.push_back(*bar);
}
基本上,有一个静态向量保存多个Foo对象,每个对象都有一个Bar对象向量。
然后我有下面的主.cpp:
#include <Foo.hpp>
#include <Bar.hpp>
int main(int argc, char *argv[])
{
Foo::printInfoStore();
Foo::getFoo("Foo1")->addBar("info11"); // info11 is not added to Foo1
Foo::printInfoStore();
Foo::getFoo("Foo1")->addBar("info12");
Foo::printInfoStore();
Foo::getFoo("Foo1")->addBar("info13");
Foo::printInfoStore();
Foo::getFoo("Foo2")->addBar("info21"); // info21 is not added to Foo2
Foo::printInfoStore();
Foo::getFoo("Foo2")->addBar("info22");
Foo::printInfoStore();
return 0;
}
输出如下所示:
InfoStore is { }
InfoStore is { Foo1=[ ] }
InfoStore is { Foo1=[ info12 ] }
InfoStore is { Foo1=[ info12 info13 ] }
InfoStore is { Foo1=[ info12 info13 ] Foo2=[ ] }
InfoStore is { Foo1=[ info12 info13 ] Foo2=[ info22 ] }
奇怪的是,为每个Foo对象(info11
和info21
)添加的第一个Bar
没有被添加,我猜测在父Foo对象之后可能会发生bars
向量的第二次初始化,但我不知道是否是这样,也找不到背后的原理。
我尝试在foo构造函数中显式初始化bars向量,但没有效果:添加的第一条总是被丢弃。
那么为什么会发生这种情况呢?我的代码有什么问题吗?可以做些什么来避免这种行为呢?
2条答案
按热度按时间jqjz2hbq1#
所有的
new
都导致内存泄漏。这些代码都不应该使用new
,因为没有任何vector
保存指针。就此而言,由于
getFoo()
总是返回一个有效的对象,无论是现有的对象还是新推送的对象,它 * 应该 * 返回一个对该对象的Foo&
引用,而不是一个Foo*
指针(如果你真的想返回一个指针,你 * 可以 * 返回一个指针,但我不建议这样做)。无论哪种方式,您都必须确保返回的内容实际上引用了
vector
内部的对象。您的输出不是您所期望的,因为代码没有正确执行此操作,这是问题的根源。当你调用
getFoo()
来得到一个不存在的对象时,你创建了一个new
对象,然后把这个对象的一个副本压入到你的vector
中,然后返回一个指向艾德对象的指针,而不是一个指向复制对象的指针。当您稍后打印vector
时,您随后存储在new
艾德对象中的任何值看起来都被丢弃,因为vector
内部的 copied 对象中不存在这些值。当你再次为一个 existing 对象调用getFoo()
时,你会返回一个指向vector
内部的 copied 对象的指针,并且不创建new
对象。类似地,
getBars()
也应该返回一个对它的vector
的 reference,而不是返回一个它的vector
的 copy。说了这么多,试试更像这样的东西:
Bar.hpp
Bar.cpp:
Foo.hpp:
Foo.cpp
main.cpp
ifmq2ha22#
将副本存储在向量中(有内存泄漏)。
固定版本:
Demo