c ++构造函数发生故障

c++ constructor malfunctioning

我正在尝试编写一个处理 linked 节点列表的 qt 小部件应用程序,该节点包含 3 个 char* 数据成员和 2 个 int 成员以及一个 "next" 指针 "node"类型, 我的问题是 linked 列表节点中的 char* 成员与第三个 char* 成员一样被保存,我尝试使用调试器并发现 所有 3 个整数的长度,即 lentitl、lenpub、lenpub 都被初始化为相同的值,并且所有 3 个 char* 成员都获得相同的值, 节点构造函数如下

node::node(char* titl,char* auth,char* pub,int pri,int stockp)
{    

    int lentitl,lenauth,lenpub;
    lenpub=strlen(pub);
    lentitl=strlen(titl);
    lenauth=strlen(auth);


    title=new char[lentitl+1];
    author=new char[lenauth+1];
    publisher=new char[lenpub+1];
    strcpy(title,titl);
    strcpy(author,auth);
    strcpy(publisher,pub);

    price=pri;
    stockposition=stockp;
    next=NULL;
}

如果从另一个名为"addbook"的class函数调用节点函数,并且从mainwindow.cpp调用addbook,addbook的函数调用如下

void MainWindow::on_addbook_clicked()
{
    char *titl,*auth,*pub;
    int pri,stockp;

    titl=ui->title->toPlainText().toLatin1().data();
    auth=ui->author->toPlainText().toLatin1().data();
    pub=ui->publisher->toPlainText().toLatin1().data();
    pri=ui->price->toPlainText().toInt();
    stockp=ui->stockposition->toPlainText().toInt();
    p.addbook(titl,auth,pub,pri,stockp);

}

node函数调用如下

void shop::addbook( char *titl, char *auth, char *pub, int pri, int stockp)
    {    
    node *p=new node(titl,auth,pub,pri,stockp);
    if(start==NULL)
        {
        start=p;
        end=p;
        }
    else
        {
        p->next=start;
        start=p;
        }    
    }

整个项目的压缩包是here here 是输出

的 link

输出的屏幕截图是

正如您在图片中看到的,在 "publisher" textedit 中输入的字符串被设置为节点的所有 3 个字符*, 谁能解释一下为什么会这样?

titl=ui->title->toPlainText().toLatin1().data();

这可能是问题所在:toLatin1() returns 一个拥有其数据的新 QByteArray。您将 QByteArray 的内部数据指针分配给 titl。但是,QByteArray 只是一个临时变量,将在下一行代码中销毁。当 QByteArray 被销毁时,它将释放其数据,这意味着您的 titl 现在指向已经释放的内存 - 即 titl 指向无效的内存位置。

建议的替代解决方案:

  1. 在您的节点 class 中使用 QString 而不是 char*,这样更容易处理内存管理问题

  2. 确保你的 QByteArray 临时文件在你需要数据的时候一直存在(直到你 strcpy 数据):

    QByteArray titl = ui->title->toPlainText().toLatin1(); QByteArray auth = ui->author->toPlainText().toLatin1(); QByteArray pub = ui->publisher->toPlainText().toLatin1(); pri=ui->price->toPlainText().toInt(); stockp=ui->stockposition->toPlainText().toInt(); p.addbook(titl.data(),auth.data(),pub.data(),pri,stockp);

我不是 Qt 专家,但就 C++ 而言,有些东西对我来说听起来不太好。您代码中的一个函数主要是 returning 一个 "char * " 指针而不是 "const char*",我说的是这些行:

   char *titl,*auth,*pub;
    int pri,stockp;

    titl=ui->title->toPlainText().toLatin1().data();

如果标题直接提供数据class我希望得到一个const char*指针,以免被修改。您可以处理 char* (或者换句话说,一个众所周知的库被设计为 return 一个非 const 指针)的唯一原因是中间有一个临时 object 或静态缓冲区调用:toLatin1 或 data.

阅读 Qt 的文档:toLatin1 是 returning 一个临时的 object,一个 QByteArray。

QByteArray  toLatin1 () const

更多信息:http://qt-project.org/doc/qt-4.8/qstring.html

所以只需像这样修改每个字符串请求:

QByteArray titlArray = ui->title->toPlainText().toLatin1();
titl=titlArray.data();

这样,当您调用

时,每个字符串都将指向一个仍然存在的缓冲区
  p.addbook(titl,auth,pub,pri,stockp);