我正在尝试编写一个处理链接节点列表的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;
}
}
的链接
输出的屏幕截图是
正如您在图像中看到的那样,在“publisher”textedit处输入的字符串将被设置为节点的所有3个char *, 谁能解释我为什么会这样呢?
答案 0 :(得分:2)
titl=ui->title->toPlainText().toLatin1().data();
这可能是个问题:toLatin1()
会返回拥有其数据的新QByteArray
。您将QByteArray
的内部数据指针分配给titl
。但是,QByteArray
只是一个临时变量,将在下一行代码中被销毁。当QByteArray
被破坏时,它将释放其数据,这意味着您的titl
现在指向已经释放的内存 - 即titl
指向无效的内存位置。
建议的解决方案替代方案:
在您的节点类中使用QString
代替char*
,更容易处理内存管理问题
只要您需要数据(确保数据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);