C++ - 类构造函数创建对象,但构造的结果是不同的

Thi*_*èle -1 c++ constructor pointers class object

我有一个C++的类项目.目标是在插入链接列表时对电话簿(txt文件)进行排序.

以下是课程:

class Person
{
    public:
        string Name
        string Firstname;
        string Adress;
        int PostalCode;
        string Telephone;
        Person();
        ~Person();
};

class Link
{
    friend class List;
    Link *next;
    Person *pers;
    public:
        Link();
        Link(string data);
};

class List
{
    // debut is the start of the chained list
    Link *start;
    public:
        List(string data)
        {
            start = NewLinkPerson(data, NULL);
        }
};

Link::Link(string data)
{
    next = NULL;
    Person p;
    p.put_data(data);
    pers = &p;
}

Link::Link()
{
    next = NULL;
    Person p;
    pers = &p;
}
Run Code Online (Sandbox Code Playgroud)

然后,NewLinkPerson函数详细说明如下:

Maillon * NewLinkPerson(string data, Maillon *ssuiv)
{
    Maillon * nouveau = new Maillon(data);
    nouveau->suiv = ssuiv;
    return nouveau;
}
Run Code Online (Sandbox Code Playgroud)

问题是创建的对象不是我命令他创建的程序的对象.如果我pers在构造函数中输出Person类型的对象,它将填充我询问的数据.但是当它离开构造函数时,数据就会消失,并且会从内存中填充随机字符串.

可能导致问题的原因是什么?我尝试了很多东西,但是它们似乎都没有用,所有这些都主要是返回了分段错误.

编辑:我忘了放在那里的功能:

void Person::put_data(string data)
{
    int sep1 = data.find("|");
    int sep2 = data.find("|", sep1+1);
    int sep3 = data.find("|", sep2+1);
    int sep4 = data.find("|", sep3+1);
    Name = data.substr(0, sep1);
    Firstname = data.substr(sep1+1, sep2-sep1-1);
    Adress = data.substr(sep2+1, sep3-sep2-1);
    Telephone = data.substr(sep4+1, data.npos);
    string ccode = data.substr(sep3+1, sep4-sep3-1);
    PostalCode = std::stoi(ccode.c_str());
}
Run Code Online (Sandbox Code Playgroud)

编辑2:翻译成英文

Nat*_*ica 6

您的代码具有未定义的行为

Link::Link(string data)
{
    next = NULL;
    Person p;
    p.put_data(data);
    pers = &p;
}

Link::Link()
{
    next = NULL;
    Person p;
    pers = &p;
}
Run Code Online (Sandbox Code Playgroud)

在上面代码的两个构造函数中,您创建一个本地Person,p然后您pers指向它.构造函数结束后p超出范围,被销毁,现在pers指向一个不再存在的对象.之后的任何解除引用pers仍将指向已删除的对象是未定义的行为.

解决这个问题只是摆脱指针pers.如果将其存储为值,则不需要任何动态内存分配,并且可以远离指针语法.链接应该是

class Link
{
    friend class List;
    Link *next;
    Person pers; // no pointer here
    public:
        Link();
        Link(string data);
};
Run Code Online (Sandbox Code Playgroud)

然后构造函数可以定义为

Link::Link(string data)
{
    next = NULL;
    pers.put_data(data);
}

Link::Link()
{
    next = NULL;
}
Run Code Online (Sandbox Code Playgroud)

如果你必须有pers一个指针,那么你可以为它分配持久存储new.如果你这样做,那么你需要delete在类的析构函数中确保它并且你有复制语义.有关这方面的更多信息,请参阅什么是三规则?