1

我有一个带有静态工厂方法的类 Foo - Foo::createOne - 它创建一个实例并将一些数据放入 std:vector 类型的私有成员变量中。当我调用 Foo::createOne 时,我的程序抛出此异常:“EXC_BAD_ACCESS(无法访问内存)”

这是代码:

Foo.h

#include <vector>

class Foo {
public:
    Foo();
    Foo(const Foo& orig);
    virtual ~Foo();

    static Foo * createOne();

private:
    std::vector<int> v;

};

Foo.cpp

#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;
}
4

4 回答 4

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将耗尽内存,并且设置指向它的指针也将是未定义的行为。

于 2013-06-10T20:54:38.870 回答
2

您应该在使用它之前创建一个 Foo 的实例。在堆上,您可以使用以下

Foo *f = new Foo();
于 2013-06-10T20:56:40.580 回答
1

您正在取消引用尚未初始化的指针:

Foo *f;  // f not pointing to a Foo instance
f->v.push_back(5);

那是未定义的行为。你必须f指出一个有效的Foo对象。

于 2013-06-10T20:54:01.343 回答
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;

}
于 2013-06-10T20:56:27.030 回答