有人可以解释为什么这段代码不起作用?当它在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;
}
答案 0 :(得分: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;
答案 1 :(得分:0)
失败可能在这里:
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;
传入数组索引作为指针过度复杂。使用引用或只传递值并返回新索引。另外,不要命名变量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;
}