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