将元素添加到struct c ++的数组
Adding element to array of struct c++
有人可以解释为什么这段代码不起作用吗?它在 addCar()
中要求输入时一直崩溃。
我认为复制数组有问题,但我不知道具体是什么。我也尝试使用 copy()
但它也没有用。
#include <iostream>
#include <string>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct Car{
string Brand;
string model;
long mileage;
};
void addCar(int *ptr, struct Car *arra){
*ptr=*ptr+1;
Car *newArr = new Car[*ptr];
memcpy(newArr, arra, (*ptr)*sizeof(Car));
cout<<"Brand ";
getline(cin,newArr[*ptr].Brand);
cout<<"Model ";
getline(cin, newArr[*ptr].model);
cout<<"mileage ";
cin>>newArr[*ptr].mileage;
arra=newArr;
};
int main(int argc, char** argv) {
int size=1;
int *ptr_size;
ptr_size=&size;
Car *tab=new Car[*ptr_size];
tab[0].Brand = "Audi";
tab[0].model = "A8";
tab[0].mileage = 14366;
addCar(*ptr_size, tab);
return 0;
}
当您将旧数组复制到新数组时,您正在访问无效内存,请记住,此时 arra 的大小为 *ptr-1 而不是 *ptr,因此该行应该是
memcpy(newArr, arra, (*ptr-1)*sizeof(Car));
同样在其他行中,您应该在 *ptr-1 位置插入新值,因为 newArr 中的索引从 0 到 size-1 即 *ptr-1:
cout<<"Brand ";
getline(cin,newArr[*ptr-1].Brand);
cout<<"Model ";
getline(cin, newArr[*ptr-1].model);
cout<<"mileage ";
cin>>newArr[*ptr-1].mileage;
失败的地方可能是:
getline(cin,newArr[*ptr].Brand);
上面一点,您这样做了:*ptr=*ptr+1;
并使 newArr
成为 *ptr
元素的数组。数组原点为零。这意味着数组中的第一项是 newArr[0]
。最后一个将在 newArr[*ptr-1]
,因此写入 newArr[*ptr]
就是覆盖其他人的内存。通常是一件坏事。
但这也不酷:
*ptr=*ptr+1;
Car *newArr = new Car[size+1];
memcpy(newArr, arra, (*ptr)*sizeof(Car));
您增加数组的大小。没关系。
您创建了一个具有新大小的新数组。没关系。
您将新大小的元素从旧数组复制到新数组并覆盖旧数组的末尾。不行。
Jerry Coffin 和 Paul McKenzie 在评论中给出了最佳答案:使用 std::vector
。如果这不允许... Ick.
不过好吧。
首先,memcpy 从字面上复制了一块内存。它不知道也不关心那块内存是什么或它包含什么。永远不要使用 memcpy 除非你正在复制一些非常非常简单的东西,比如基本数据类型或者只由基本数据类型组成的结构。字符串不是基本的。字符串表示的数据可能不在字符串内部。在这种情况下,您复制一个指向字符串的指针,并且该指针在字符串死亡后将无效。这对你来说不是问题,因为你没有杀死字符串。这导致了问题 2。让我们在到达那里之前解决它。最简单的方法(除了 vector
)将是:
for (int index = 0; index < *ptr-1; index++)
{
newArr[index] = arra[index];
}
一个优化说明。您不想每次添加到数组时都调整大小和复制数组。考虑有两个整数,一个是数组的大小,另一个是数组的索引,每次索引即将赶上数组的大小时,将数组的大小加倍。
当您使用 new
为数据分配任何内存时,必须有人清理并使用 delete
放回该内存。在 C++ 中,某人就是你。所以,在 arra=newArr;
之前,您需要 delete[] arra;
将数组索引作为指针传递过于复杂。使用引用或仅按值传递和 return 新索引。另外,不要命名变量 ptr。使用描述性的东西。
void addCar(int &arrasize, struct Car *arra){
或
int addCar(int arrasize, struct Car *arra){
下一个问题:int addCar(int arrasize, struct Car *arra){
传入一个指向arra的指针。但是你按值传递了指针,制作了指针的副本,所以当你在函数内更改指针时,只有副本被更改,新数组不会再次出现。所以,
int addCar(int arrasize, struct Car * & arra){
传入指针的引用并允许您在函数内修改指针。
将所有这些放在一起:
int addCar(int size, struct Car * & arra)
{
Car *newArr = new Car[size + 1];
for (int index = 0; index < size; index++)
{
newArr[index] = arra[index];
}
cout << "Brand ";
getline(cin, newArr[size].Brand);
cout << "Model ";
getline(cin, newArr[size].model);
cout << "mileage ";
cin >> newArr[size].mileage;
delete[] arra;
arra = newArr;
return size+1;
}
int main()
{
int size=1;
Car *tab=new Car[size];
tab[0].Brand = "Audi";
tab[0].model = "A8";
tab[0].mileage = 14366;
size = addCar(size, tab);
// do more stuff;
// bit of test code here
for (int index = 0; index < size; index++)
{
cout << "Car " << index << " brand =" <<tab[index].Brand << " Model=" << tab[index].model << " mileage=" <<tab[index].mileage << endl;
}
delete[] tab;
return 0;
}
有人可以解释为什么这段代码不起作用吗?它在 addCar()
中要求输入时一直崩溃。
我认为复制数组有问题,但我不知道具体是什么。我也尝试使用 copy()
但它也没有用。
#include <iostream>
#include <string>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct Car{
string Brand;
string model;
long mileage;
};
void addCar(int *ptr, struct Car *arra){
*ptr=*ptr+1;
Car *newArr = new Car[*ptr];
memcpy(newArr, arra, (*ptr)*sizeof(Car));
cout<<"Brand ";
getline(cin,newArr[*ptr].Brand);
cout<<"Model ";
getline(cin, newArr[*ptr].model);
cout<<"mileage ";
cin>>newArr[*ptr].mileage;
arra=newArr;
};
int main(int argc, char** argv) {
int size=1;
int *ptr_size;
ptr_size=&size;
Car *tab=new Car[*ptr_size];
tab[0].Brand = "Audi";
tab[0].model = "A8";
tab[0].mileage = 14366;
addCar(*ptr_size, tab);
return 0;
}
当您将旧数组复制到新数组时,您正在访问无效内存,请记住,此时 arra 的大小为 *ptr-1 而不是 *ptr,因此该行应该是
memcpy(newArr, arra, (*ptr-1)*sizeof(Car));
同样在其他行中,您应该在 *ptr-1 位置插入新值,因为 newArr 中的索引从 0 到 size-1 即 *ptr-1:
cout<<"Brand ";
getline(cin,newArr[*ptr-1].Brand);
cout<<"Model ";
getline(cin, newArr[*ptr-1].model);
cout<<"mileage ";
cin>>newArr[*ptr-1].mileage;
失败的地方可能是:
getline(cin,newArr[*ptr].Brand);
上面一点,您这样做了:*ptr=*ptr+1;
并使 newArr
成为 *ptr
元素的数组。数组原点为零。这意味着数组中的第一项是 newArr[0]
。最后一个将在 newArr[*ptr-1]
,因此写入 newArr[*ptr]
就是覆盖其他人的内存。通常是一件坏事。
但这也不酷:
*ptr=*ptr+1;
Car *newArr = new Car[size+1];
memcpy(newArr, arra, (*ptr)*sizeof(Car));
您增加数组的大小。没关系。
您创建了一个具有新大小的新数组。没关系。
您将新大小的元素从旧数组复制到新数组并覆盖旧数组的末尾。不行。
Jerry Coffin 和 Paul McKenzie 在评论中给出了最佳答案:使用 std::vector
。如果这不允许... Ick.
不过好吧。
首先,memcpy 从字面上复制了一块内存。它不知道也不关心那块内存是什么或它包含什么。永远不要使用 memcpy 除非你正在复制一些非常非常简单的东西,比如基本数据类型或者只由基本数据类型组成的结构。字符串不是基本的。字符串表示的数据可能不在字符串内部。在这种情况下,您复制一个指向字符串的指针,并且该指针在字符串死亡后将无效。这对你来说不是问题,因为你没有杀死字符串。这导致了问题 2。让我们在到达那里之前解决它。最简单的方法(除了 vector
)将是:
for (int index = 0; index < *ptr-1; index++)
{
newArr[index] = arra[index];
}
一个优化说明。您不想每次添加到数组时都调整大小和复制数组。考虑有两个整数,一个是数组的大小,另一个是数组的索引,每次索引即将赶上数组的大小时,将数组的大小加倍。
当您使用 new
为数据分配任何内存时,必须有人清理并使用 delete
放回该内存。在 C++ 中,某人就是你。所以,在 arra=newArr;
之前,您需要 delete[] arra;
将数组索引作为指针传递过于复杂。使用引用或仅按值传递和 return 新索引。另外,不要命名变量 ptr。使用描述性的东西。
void addCar(int &arrasize, struct Car *arra){
或
int addCar(int arrasize, struct Car *arra){
下一个问题:int addCar(int arrasize, struct Car *arra){
传入一个指向arra的指针。但是你按值传递了指针,制作了指针的副本,所以当你在函数内更改指针时,只有副本被更改,新数组不会再次出现。所以,
int addCar(int arrasize, struct Car * & arra){
传入指针的引用并允许您在函数内修改指针。
将所有这些放在一起:
int addCar(int size, struct Car * & arra)
{
Car *newArr = new Car[size + 1];
for (int index = 0; index < size; index++)
{
newArr[index] = arra[index];
}
cout << "Brand ";
getline(cin, newArr[size].Brand);
cout << "Model ";
getline(cin, newArr[size].model);
cout << "mileage ";
cin >> newArr[size].mileage;
delete[] arra;
arra = newArr;
return size+1;
}
int main()
{
int size=1;
Car *tab=new Car[size];
tab[0].Brand = "Audi";
tab[0].model = "A8";
tab[0].mileage = 14366;
size = addCar(size, tab);
// do more stuff;
// bit of test code here
for (int index = 0; index < size; index++)
{
cout << "Car " << index << " brand =" <<tab[index].Brand << " Model=" << tab[index].model << " mileage=" <<tab[index].mileage << endl;
}
delete[] tab;
return 0;
}