创建和清除结构数组
Creating and clearing an array of structures
我一直在尝试编写一个简短的程序,允许用户将条目添加到"数据库"中,列出他们输入的条目,以及清除所有条目而不结束程序的能力。这是我得到的
#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++的内容。所以除非代码运行绝对必要,否则请不要引入任何新的噱头=)
将所有ptrarr[counter][1]
替换为 ptrarr[counter][0]
可以解决问题。
进一步建议:
I. 此代码具有冗余:
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
将其替换为:
ID *ptrarr;
ptrarr = new ID [10];
那么你不需要在每个 ptrarr[计数器] 的末尾额外 [0]
II. 函数使您的代码更具可读性:
if(command=="add")
add();
else if(command=="list")
list();
else if(command=="clear")
clear();
else if(command=="exit")
return 0;
else
cout << "try again" << endl;
然后在较小的领域做出决策(大型程序的良好做法)。
III. 您的代码中还有一个错误:
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
在这里,您应该重置计数器。另外,如果你考虑我的观点(I),这部分很好。否则,如果你用new
和for
循环,恐怕也需要用for
循环delete
。仅仅删除数组树的根就会带来内存泄漏!
另外,如果您通过删除清除列表,您是否不再需要在列表中存储数据?在链表中使用删除是一个好主意,但在这里不适用。只需重置计数器即可完成工作,并且它不再在列表中显示 ID。列表中的for
仅计入计数器。
如果退出程序,不释放内存吗?
我说
delete [] ptrarr;
适合在出口处。
您正在创建一个指针数组,每个指针都指向一个元素:
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
,这将再次导致未定义的行为,因为您只为ptrarr
分配了10
指针。
删除内容
您正在使用:
else if(command=="clear")
{
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
这有几个问题:
您有内存泄漏。你从不就
ptrarr[0] - ptrarr[9]
指向的内容打电话给delete []
。您必须使用: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]
。
在 while
语句的表达式中使用 MAX_ITEMS
而不是幻数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;
}
数组索引从 0 开始。
ptrarr[counter][1]
是指ptrarr[counter]
的第二个元素。 ptrarr[counter]
指向一个元素的数组。
试试这个:
if(command=="add") {
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][0].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][0].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][0].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][0].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][0].date.year;
counter++;
}
else if(command=="list") {
for (int i=0; i<counter; i++){
int n=i+1;
cout << n << " "<< ptrarr[i][0].name << " ";
if (ptrarr[i][0].vip){
cout << "VIP ";
}
cout << "Score: " << ptrarr[i][0].score << " "
<< "Born: " << ptrarr[i][0].date.month << "/" << ptrarr[i][0].date.year << endl;
}
}
结语 :
- 就像你用 0 初始化
counter
一样,你应该使用 0 索引来访问第一个元素; - 上市时也是如此。
- 数组基于 0 索引。
- 从函数中全局删除并重新实例化数组结构,而无需在编译时知道数组的大小
- 如何使用函数的输出初始化 const 数组结构字段?
- 传递数组结构、ofstream 和 interger 以运行
- 从文本文件中读取并输入到数组结构中,然后显示读取的数据C++
- 将文本文件读取到数组结构中
- C/C++中数组结构和数组结构的通用接口
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- C++ 使用数组结构创建平衡的二叉搜索树
- C++:释放动态数组(结构成员)和指向此结构的指针的方法
- 使用 vector 在 c++ 中声明 3D 数组结构
- 数组结构无法正确打印
- 如何在C++中访问数组结构内部的数组结构
- CIN进入数组结构似乎什么也没输入
- ifstream将数组结构到txt文件中,然后尽可能将其提取为数组
- wlanapi-将WlanFreeMemory释放其WLAN_INTERFACE_INFO数组结构
- 显示数组结构 c++
- C++ 使用函数访问数组结构的方法是什么?
- 将庞大的数组结构复制到 GPU
- 如何封送包含字符矩阵的数组结构
- C++多维数组结构的对齐