C++构造函数故障
我正在尝试编写一个qt小部件应用程序,它处理节点的链表,该节点包含3个char*数据成员和2个int成员以及一个节点类型的下一个指针, 我的问题是链表节点中的char*成员与第三个char*成员的保存方式相同,我尝试使用调试器发现 所有3个整数(即lentitl、lenpub、lenpub)的长度都初始化为相同的值,并且所有3个char*成员都得到相同的值, 节点构造函数如下所示C++构造函数故障,c++,qt,constructor,C++,Qt,Constructor,我正在尝试编写一个qt小部件应用程序,它处理节点的链表,该节点包含3个char*数据成员和2个int成员以及一个节点类型的下一个指针, 我的问题是链表节点中的char*成员与第三个char*成员的保存方式相同,我尝试使用调试器发现 所有3个整数(即lentitl、lenpub、lenpub)的长度都初始化为相同的值,并且所有3个char*成员都得到相同的值, 节点构造函数如下所示 node::node(char* titl,char* auth,char* pub,int pri,int sto
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;
}
}
节点的函数调用如下
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个字符*,
谁能解释一下为什么会这样
titl=ui->title->toPlainText().toLatin1().data();
这可能就是问题所在:toLatin1返回一个拥有其数据的新QByteArray。将该QByteArray的内部数据指针指定给titl。但是,QByteArray只是一个临时变量,将在下一行代码中销毁。当QByteArray被销毁时,它将释放其数据,这意味着您的titl现在指向已释放的内存,即titl指向无效的内存位置
建议的解决方案备选方案:
在节点类中使用QString而不是char*,这样更容易处理内存管理问题
确保您的QByteArray在您需要数据之前一直处于临时状态,直到您复制数据为止:
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、 addbooktitl.data,auth.data,pub.data,pri,stockp
这可能就是问题所在:toLatin1返回一个拥有其数据的新QByteArray。将该QByteArray的内部数据指针指定给titl。但是,QByteArray只是一个临时变量,将在下一行代码中销毁。当QByteArray被销毁时,它将释放其数据,这意味着您的titl现在指向已释放的内存,即titl指向无效的内存位置
建议的解决方案备选方案:
在节点类中使用QString而不是char*,这样更容易处理内存管理问题
确保您的QByteArray在您需要数据之前一直处于临时状态,直到您复制数据为止:
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、 addbooktitl.data,auth.data,pub.data,pri,stockp
我不是QT专家,但是在C++方面有一些听起来不太好的东西。代码中的一个函数主要返回char*指针,而不是const char*,我要说的是以下几行:
char *titl,*auth,*pub;
int pri,stockp;
titl=ui->title->toPlainText().toLatin1().data();
如果数据是由title类直接提供的,我希望获得一个const char*指针,以便不允许修改它。唯一可以处理char *或换句话说,一个众所周知的库的原因是为了返回一个非const指针,即在调用中间有一个临时对象或一个静态缓冲区:TelaTIL1或DATA。
读取Qt:toLatin1的文档将返回一个临时对象QByteArray
QByteArray toLatin1 () const
有关更多信息:
因此,只需修改每个字符串请求,如下所示:
QByteArray titlArray = ui->title->toPlainText().toLatin1();
titl=titlArray.data();
这样,当您调用时,每个字符串都将指向一个仍然存在的缓冲区
p.addbook(titl,auth,pub,pri,stockp);
我不是QT专家,但是在C++方面有一些听起来不太好的东西。代码中的一个函数主要返回char*指针,而不是const char*,我要说的是以下几行:
char *titl,*auth,*pub;
int pri,stockp;
titl=ui->title->toPlainText().toLatin1().data();
如果数据是由title类直接提供的,我希望获得一个const char*指针,以便不允许修改它。唯一可以处理char *或换句话说,一个众所周知的库的原因是为了返回一个非const指针,即在调用中间有一个临时对象或一个静态缓冲区:TelaTIL1或DATA。
读取Qt:toLatin1的文档将返回一个临时对象QByteArray
QByteArray toLatin1 () const
有关更多信息:
因此,只需修改每个字符串请求,如下所示:
QByteArray titlArray = ui->title->toPlainText().toLatin1();
titl=titlArray.data();
这样,当您调用时,每个字符串都将指向一个仍然存在的缓冲区
p.addbook(titl,auth,pub,pri,stockp);
ui->title==ui->author==ui->publisher?ui->title==ui->author==ui->publisher?我想在任何地方都使用qString作为“最后手段”,因此我没有在构造函数中使用它。不管怎样,谢谢你,成功了@Anuj你为什么不使用QString?是的,我想学习转换,所以避免使用QString
是的,它们非常容易使用。我想在任何地方都使用qstring作为“最后手段”,因此我没有在构造函数中使用它。不管怎样,谢谢你,成功了@Anuj你为什么不使用QString?是的,我想学习转换,所以避免使用QString,是的,它们很容易使用