将元素添加到struct c ++数组中

时间:2015-05-19 21:03:52

标签: c++ arrays struct

有人可以解释为什么这段代码不起作用?当它在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;    
}

2 个答案:

答案 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;
}