c ++构造函数失灵

时间:2015-01-22 17:36:32

标签: c++ qt constructor

我正在尝试编写一个处理链接节点列表的qt小部件应用程序,该节点包含3个char *数据成员和2个int成员以及一个“node”类型的“next”指针, 我的问题是链表的节点中的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”的类函数调用节点函数,并且从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);

}

节点的函数调用如下

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

整个项目的邮编是herehere是输出

的链接

输出的屏幕截图是here

正如您在图像中看到的那样,在“publisher”textedit处输入的字符串将被设置为节点的所有3个char *, 谁能解释我为什么会这样呢?

2 个答案:

答案 0 :(得分:2)

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

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

建议的解决方案替代方案:

  1. 在您的节点类中使用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->对价格> toPlainText()toInt(); stockp = UI-> stockposition-> toPlainText()toInt(); p.addbook(titl.data(),auth.data(),pub.data(),PRI,stockp);

答案 1 :(得分:2)

我不是Qt的专家,但就C ++而言,有些事情对我来说并不好听。代码中的一个函数主要是返回一个" char *"指针而不是" const char *",我正在谈论这些界限:

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

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

如果数据是由标题类直接提供的,我希望获得一个const char *指针,以便不允许修改它。你可以处理char *(或者换句话说,一个众所周知的库被设计为返回非const指针)的唯一原因是在调用中间有一个临时对象或一个静态缓冲区:toLatin1或data。< / p>

阅读Qt的文档:toLatin1返回一个临时对象,一个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);