访问使用 malloc 分配的C++对象的成员



[编者注:我已经编辑了标题,试图使它在未来对其他人有用。 为了给回答者加分,当他们回答它时,这只是一个"为什么这不起作用?"的问题!

以下代码在top -> ...行崩溃并出现分段错误,无论尝试将什么Node*推送到向量子级上。有谁知道可能导致这种情况的原因?

struct Node
{
    string data;
    struct Node* parent;
    vector<struct Node*> children;
};
struct Node* push(string word, struct Node* top)
{
    Node* temp = (struct Node*) malloc(sizeof(struct Node));
    temp -> data = word;
    temp -> parent = top;
    return temp;
}
int main()
{
    Node* top = push("blah", NULL);
    Node* temp = NULL;
    top -> children.push_back(temp);
}

问题是malloc不会调用构造函数。 你指望要构建的向量children

取代:

Node* temp = (struct Node*) malloc(sizeof(struct Node));

跟:

Node* temp = new Node;

malloc(来自 C(和new(来自 C++(都将分配您需要的内存,但只有new会调用所需的构造函数,因为 C 不使用它们。 如果您不确定需要 malloc,请使用 new。

您不要在对象上使用malloc,而应该改用newmalloc 是一个 C 函数,它只分配一块内存,而 C++ 运算符std::new还负责对象的初始化和构造 - 您在这里错过了并给您带来麻烦的步骤(例如,在您的情况下从未调用过 temp->children 的构造函数(。

根据经验:如果您正在编写C++代码,则应使用 C++ 运算符 std::newstd::delete 进行动态内存分配和释放,而不是 C 函数。

您的问题是您的children向量未正确初始化。你应该使用 Node* temp = new Node; 而不是 malloc 来调用 Node 的构造函数,这会调用 children 的构造函数,从而正确地初始化vector

正如其他人评论的那样,看起来你来自C,需要一本好C++书。C++不仅仅是"C with class es"!

您的push函数看起来非常像它应该是一个构造函数。构造函数在分配所需的内存并执行必要的初始化后由new调用。如果您不提供编译器,编译器将为您生成一个(它还将提供一个复制构造函数和一个赋值运算符(请参阅什么是三法则?

由于您调用了malloc()而不是new,因此未调用合成的默认构造函数,因此未初始化children vector,从而导致访问冲突。

在这里,我演示了如何实现默认构造函数(并禁用其他两个(,以启动class(或struct(的三个数据成员中的每一个:

#include <string>
#include <vector>
using std::vector;
using std::string;
class Node
{
public:
    Node(const string& word, Node* top)
        :data(word)
        ,parent(top)
        ,children()
    {
        if (top != NULL)
        {
            top->children.push_back(this);
        }
    }
    virtual ~Node()
    {
        std::vector<Node*>::iterator i = std::find(children.begin(), children.end(), this);
        if (i != children.end())
        {
            parent->children.erase(i);
        }
        // TODO: You may wish to destory children at this point
    }
private:
    Node(const Node& disable);
    Node& operator =(const Node& disable);
private:
    string data;
    Node* parent;
    vector<Node*> children;
};
int main()
{
    Node top("blah", NULL);
    Node child("foo", &top);
}

我还实现了一个析构函数,它在销毁时从其父节点的子节点中删除节点。

malloc(( 只是分配一个空的内存块,你应该使用 new(( 运算符初始化所有成员对象;

Node* temp = new Node();

相关内容

  • 没有找到相关文章

最新更新