使用 C++ 动态分配结构数组
Dynamically allocate an array of structs with C++
我正在尝试动态分配记录数组。当我 运行 我的程序与 ./a.out 它似乎工作正常但是当我尝试 运行 程序从 .txt 文件 (./myProg < ) 输入数据时它反复记录整个数组中的第一行文本并崩溃,最后不打印出所选的书。我的猜测是我没有正确创建数组,但我似乎无法弄清楚我的问题是什么。
struct Book {
char *title; //entered with no spaces
int date; // in the form ddmmyy
};
Book *createRecord(int);
void input(Book *, int);
void display(Book *, int, int);
void destroyRecord(Book *);
int main() {
int arrN = 0;
int n = 0;
cout << "Enter size of array: ";
cin >> arrN;
Book *bookArr;
bookArr = new Book[arrN];
bookArr = createRecord(arrN);
input(bookArr, arrN);
cin.ignore();
cout << "Book: ";
cin >> n;
display(bookArr, arrN, n);
destroyRecord(bookArr);
return EXIT_SUCCESS;
}
Book *createRecord(int arrN){
struct Book *bookArr;
bookArr = new Book[arrN];
return bookArr;
}
void input(Book *bookArr, int arrN) {
for(int i = 0; i < arrN; i++){
char arrFirst[20];
cin.ignore();
cout << "Name: ";
cin.getline(arrFirst, 20);
strcpy((bookArr[i]).title = new char, arrFirst);
cout << "Score: ";
cin >> (bookArr[i]).date;
}
}
void display(Book *bookArr, int arrN, int n) {
if (0 <= n && n <= arrN){
cout << (bookArr[n-1]).title << " " << (bookArr[n-1]).date << endl;
}
}
void destroyRecord(Book *bookArr) {
delete [] (bookArr)->title;
delete bookArr;
}
嗯,首先,您要分配两个数组:
bookArr = new Book[arrN]; // <-- leaked
bookArr = createRecord(arrN);
那是内存泄漏。
其次:
(bookArr[i]).title = new char
这是分配一个字符,您正试图将整个字符串复制到该字符中。那应该是:
// two lines please!
bookArr[i].title = new char[20];
strcpy(bookArr[i].title, arrFirst);
第三:
if (0 <= n && n <= arrN){
边界检查不正确。上限应该是n < arrN
,然后就是索引n
。通过索引 n - 1
,您可以打印第 -1 个索引。
最后但并非最不重要的一点是:
struct Book {
std::string title;
int date;
}
std::vector<Book> bookArr;
问题 1:
修复显示函数中的数组索引问题:
void display(Book *bookArr, int arrN, int n) {
if (0 <= n && n <= arrN){
cout << (bookArr[n - 1]).title << " " << (bookArr[n - 1]).date << endl;
}
}
至
void display(Book *bookArr, int arrN, int n) {
if (0 < n && n <= arrN){
cout << (bookArr[n - 1]).title << " " << (bookArr[n - 1]).date << endl;
}
}
当 n = 0
、bookArr[-1]
在您的代码中抛出错误时。
问题 2:
将字符数组而不是单个字符分配给行中的标题,更改:
strcpy((bookArr[i]).title = new char, arrFirst);
至
strcpy((bookArr[i]).title = new char[20], arrFirst);
不确定输入问题,但您肯定没有按应有的方式创建数组。在您的代码中,您正在创建一个书籍数组,然后在 createRecord 函数中分配一个新的书籍数组并用它替换原始数组。与您预期发生的情况不同,您最终会得到一组未初始化的 Book 指针。
这是你应该做的...
// Allocate an array of books
Book *bookArr;
bookArr = new Book[arrN];
// Preallocate the records
for ( int iBook = 0; iBool < arrN; iBook++ )
{
bookArr[ iBook ] = createRecord();
}
...
Book *createRecord()
{
// Allocate one new book
struct Book *pbook = new book;
return pbook;
}
我正在尝试动态分配记录数组。当我 运行 我的程序与 ./a.out 它似乎工作正常但是当我尝试 运行 程序从 .txt 文件 (./myProg < ) 输入数据时它反复记录整个数组中的第一行文本并崩溃,最后不打印出所选的书。我的猜测是我没有正确创建数组,但我似乎无法弄清楚我的问题是什么。
struct Book {
char *title; //entered with no spaces
int date; // in the form ddmmyy
};
Book *createRecord(int);
void input(Book *, int);
void display(Book *, int, int);
void destroyRecord(Book *);
int main() {
int arrN = 0;
int n = 0;
cout << "Enter size of array: ";
cin >> arrN;
Book *bookArr;
bookArr = new Book[arrN];
bookArr = createRecord(arrN);
input(bookArr, arrN);
cin.ignore();
cout << "Book: ";
cin >> n;
display(bookArr, arrN, n);
destroyRecord(bookArr);
return EXIT_SUCCESS;
}
Book *createRecord(int arrN){
struct Book *bookArr;
bookArr = new Book[arrN];
return bookArr;
}
void input(Book *bookArr, int arrN) {
for(int i = 0; i < arrN; i++){
char arrFirst[20];
cin.ignore();
cout << "Name: ";
cin.getline(arrFirst, 20);
strcpy((bookArr[i]).title = new char, arrFirst);
cout << "Score: ";
cin >> (bookArr[i]).date;
}
}
void display(Book *bookArr, int arrN, int n) {
if (0 <= n && n <= arrN){
cout << (bookArr[n-1]).title << " " << (bookArr[n-1]).date << endl;
}
}
void destroyRecord(Book *bookArr) {
delete [] (bookArr)->title;
delete bookArr;
}
嗯,首先,您要分配两个数组:
bookArr = new Book[arrN]; // <-- leaked
bookArr = createRecord(arrN);
那是内存泄漏。
其次:
(bookArr[i]).title = new char
这是分配一个字符,您正试图将整个字符串复制到该字符中。那应该是:
// two lines please!
bookArr[i].title = new char[20];
strcpy(bookArr[i].title, arrFirst);
第三:
if (0 <= n && n <= arrN){
边界检查不正确。上限应该是n < arrN
,然后就是索引n
。通过索引 n - 1
,您可以打印第 -1 个索引。
最后但并非最不重要的一点是:
struct Book {
std::string title;
int date;
}
std::vector<Book> bookArr;
问题 1:
修复显示函数中的数组索引问题:
void display(Book *bookArr, int arrN, int n) {
if (0 <= n && n <= arrN){
cout << (bookArr[n - 1]).title << " " << (bookArr[n - 1]).date << endl;
}
}
至
void display(Book *bookArr, int arrN, int n) {
if (0 < n && n <= arrN){
cout << (bookArr[n - 1]).title << " " << (bookArr[n - 1]).date << endl;
}
}
当 n = 0
、bookArr[-1]
在您的代码中抛出错误时。
问题 2:
将字符数组而不是单个字符分配给行中的标题,更改:
strcpy((bookArr[i]).title = new char, arrFirst);
至
strcpy((bookArr[i]).title = new char[20], arrFirst);
不确定输入问题,但您肯定没有按应有的方式创建数组。在您的代码中,您正在创建一个书籍数组,然后在 createRecord 函数中分配一个新的书籍数组并用它替换原始数组。与您预期发生的情况不同,您最终会得到一组未初始化的 Book 指针。
这是你应该做的...
// Allocate an array of books
Book *bookArr;
bookArr = new Book[arrN];
// Preallocate the records
for ( int iBook = 0; iBool < arrN; iBook++ )
{
bookArr[ iBook ] = createRecord();
}
...
Book *createRecord()
{
// Allocate one new book
struct Book *pbook = new book;
return pbook;
}