我一直在尝试编写一个简短的程序,允许用户将条目添加到“数据库”中,列出他们已放入的条目,并能够清除所有条目而无需结束程序。这就是我所拥有的
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
struct BIRTH
{int month; int year;};
struct ID
{string name; bool vip; float score;
struct BIRTH date;} ;
int main(int argc, char** argv) {
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
int counter = 0;
while(counter<100){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][1].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][1].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][1].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][1].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][1].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{int n=i+1;
cout << n << " "
<< ptrarr[i][1].name << " ";
if (ptrarr[i][1].vip)
{cout << "VIP ";}
cout << "Score: " << ptrarr[i][1].score << " "
<< "Born: " << ptrarr[i][1].date.month << "/" << ptrarr[i][1].date.year << endl;
}
}
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
else if(command=="exit")
{return 0;}
else
cout << "try again" << endl;
}
return 0;
}
现在要解决的是:以下代码成功编译,但是当我键入“ add”命令时,程序崩溃(成就已解锁,认为用这样短的代码无法获得)。最重要的是,该数组由多类型结构组成,并且“ clear”命令清除了数组中的所有条目。
注意:我知道有上千种更好的方法来编写这段代码,但是我正在编写它来练习到目前为止我所介绍的有关C ++的内容。因此,除非绝对有必要运行代码,否则请不要引入任何新的gi头=)
您正在创建一个指针数组,每个指针都指向一个元素:
ptrarr[r] = new ID[1] ;
可以使用的最大索引ptrarr[r]
为0
。由于您正在使用ptrarr[counter][1]
,因此您正在访问超出范围的内存。这导致未定义的行为。崩溃就是这样一种未定义的行为。
您的代码中还有其他问题可能需要修复。
更多超出范围的内存访问
您正在使用:
int counter = 0;
while(counter<100){
...
getline (cin,ptrarr[counter][1].name);
如果counter > 10
由于仅分配了的10
指针,那将再次导致未定义的行为ptrarr
。
删除内容
您正在使用:
else if(command=="clear")
{
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
这有几个问题:
您有内存泄漏。您永远不会要求指向delete []
什么ptrarr[0] - ptrarr[9]
。您必须使用:
else if(command=="clear")
{
for ( int i = 0; i < 10; ++i )
{
delete [] ptrarr[i];
}
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
请记住,每个分配必须有一个对应的解除分配。否则,您正在泄漏内存。
一旦调用delete [] ptrarr;
,它就会指向悬挂的内存。ptrarr
在您继续使用内存时,我看不到任何重新分配内存的代码。
您需要重新分配内存并将其重置counter
为0
用户选择“清除”时的状态。
我的建议
您没有两个级别的指针。您只需要以下内容:
int const MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
而是ptrarr[counter][1]
使用IDarr[counter]
。
使用MAX_ITEMS
的表达while
语句,而不是一个神奇的数字100
。
int counter = 0;
while(counter<MAX_ITEMS){
在处理“清除”时,您无需取消分配或分配内存。只需重置即可counter
。
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
从中返回之前,请确保先释放内存main
。
这是main
带有更改的完整功能:
int main(int argc, char** argv) {
const int MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
int counter = 0;
while(counter < MAX_ITEMS){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin, IDarr[counter].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> IDarr[counter].vip;
cout << "Enter score" << endl;
cin >> IDarr[counter].score;
cout << "Month of birth" << endl;
cin >> IDarr[counter].date.month;
cout << "Year of birth" << endl;
cin >> IDarr[counter].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{
int n=i+1;
cout << n << " " << IDarr[i].name << " ";
if (IDarr[i].vip)
{
cout << "VIP ";
}
cout
<< "Score: " << IDarr[i].score << " "
<< "Born: " << IDarr[i].date.month << "/" << IDarr[i].date.year << endl;
}
}
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
else if(command=="exit")
{
// Don't use return 0;
// Just break out of the while loop so that memory
// can be deallocated at the end of this function.
break;
}
else
cout << "try again" << endl;
}
delete [] IDarr;
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句