我有一个带有静态工厂方法的类Foo - Foo :: createOne - 它创建一个实例并将一些数据放入std:vector类型的私有成员变量中。当我调用Foo :: createOne时,我的程序抛出此异常:“EXC_BAD_ACCESS(无法访问内存)”
以下是代码:
#include <vector>
class Foo {
public:
Foo();
Foo(const Foo& orig);
virtual ~Foo();
static Foo * createOne();
private:
std::vector<int> v;
};
#include "Foo.h"
Foo::Foo() {
};
Foo::Foo(const Foo& orig) {
};
Foo::~Foo() {
};
Foo * Foo::createOne() {
Foo *f;
f->v.push_back(5);
return f;
}
#include <iostream>
#include "Foo.h"
int main(int argc, char** argv) {
std::cout << "Testing createOne." << std::endl;
Foo *myFoo = Foo::createOne();
std::cout << "It worked." << std::endl;
}
感谢您的回答。我修复了未初始化的指针问题(如下)。现在,我收到一个编译器警告“返回局部变量'f'的地址”
Foo * Foo::createOne() {
Foo f;
f.v.push_back(5);
return &f;
}
答案 0 :(得分:2)
Foo *f;
f->v.push_back(5);
第一行是创建一个原始的,未初始化的指针。它不是变量的实例,因此尝试取消引用它是 Undefined Behavior 。
您需要将其初始化为一个实例,如下所示:
Foo *f = new Foo();
f->v.push_back(5);
// ...
delete f;
只有这样,您的代码才会生效。
更新:再次检查您的代码后,我现在意识到您使用指针是完全没必要的。你可以通过返回值来做同样的事情:
Foo Foo::createOne()
{
Foo f;
f.v.push_back(5);
return f;
}
您收到错误address of local variable f returned
的原因是因为您返回了指向临时值的指针。当函数结束时,局部变量f
将耗尽内存,并且设置指向它的指针也将是Undefined Behavior。
答案 1 :(得分:2)
在使用Foo之前,您应该创建一个Foo实例。 在堆上,您可以使用以下
Foo *f = new Foo();
答案 2 :(得分:1)
您正在取消引用尚未初始化的指针:
Foo *f; // f not pointing to a Foo instance
f->v.push_back(5);
这是未定义的行为。您必须使f
指向有效的Foo
对象。
答案 3 :(得分:1)
在C ++中声明指针时,需要手动调用构造函数,如下所示:
Foo * Foo::createOne() {
Foo *f = new Foo; // <<=== Here
f->v.push_back(5);
return f;
}
这与定义为对象的对象不同,而不是指针:
Foo Foo::createOne() {
Foo f; // No initializer is necessary
f.v.push_back(5);
return f;
}
在这种情况下,对象按值返回,因此其内容将在进程中复制。
当您动态创建对象时,需要删除指针指向的对象以避免内存泄漏,如下所示:
int main(int argc, char** argv) {
std::cout << "Testing createOne." << std::endl;
Foo *myFoo = Foo::createOne();
std::cout << "It worked." << std::endl;
delete myFoo;
}