简体   繁体   中英

C++: vector in struct, push_back error

I am trying to save the data in a vector in structs. Since I do not know the length of each data, I used push_back . However, the for loop does not work and I got Command terminated after the first i loop.

I tried several answers like this , but none of them works.

Here is a simplified version of what I tried (and gives the same error):

#include <iostream>
#include <vector>

using namespace std;

typedef struct{
    vector<int> words;
}DATA_STRUCT;

void add(DATA_STRUCT *data){
    for(int i=0; i<5; i++){
        for(int s=0;s<3; s++){
            (&data)[i] -> words.push_back(s);
            cout << i << s << endl;
        }
    }
}

int main(){
    DATA_STRUCT *data = new DATA_STRUCT[5];
    add(data);
    cout << (&data)[0] -> words[0] << endl;
}

The problem lies with:

(&data)[i] -> words.push_back(s);

&data evaluates to a DATA_STRUCT **data . By using (&data)[i] , you are accessing memory that you are not supposed to, which causes undefined behavior.

That line can be a lot simpler.

data[i].words.push_back(s);

You are almost there. Here is the correct approach :-

#include <iostream>
#include <vector>

using namespace std;

typedef struct{
    vector<int> words;
}DATA_STRUCT;

void add(DATA_STRUCT *data){
    for(int i=0; i<5; i++){
        for(int s=0;s<3; s++){
            data[i].words.push_back(s);  //<-- edit
            cout << i << s << endl;
        }
    }
}

int main(){
    DATA_STRUCT *data = new DATA_STRUCT[5]; 
    add(data);
    cout << data[0].words[0] << endl;  //<-- edit
    delete[] data;                     //Thank juanchopanz
}

Live demo

&data is wrong, you want the value.
data[xxx] works like the "get value" operation. (roughly speaking)

Edit

There is also memory leak at :-

DATA_STRUCT *data = new DATA_STRUCT[5];  

It is new without delete , so I also add delete[] data; . (Thank juanchopanza )

Edit2

To answer Tom de Geus :-

Any way to avoid the new here?

Here is the better version :-

DATA_STRUCT data[5];
add(data);
cout << data[0].words[0] << endl;

Live demo

Edit2

To answer additional question from OP :-

Why can we use arrow instead of dot? Is data in the add function a struct of pointer?

data is DATA_STRUCT*
(&data) is DATA_STRUCT**
(&data)[i] is DATA_STRUCT*
(&data)[i]-> is DATA_STRUCT
(&data)[i]->words is DATA_STRUCT::words

It is a wrong address, but in term of (only) syntax, it is correct.
Wrong address ~ undefined behavior = can work OK / work but wrong / crash

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM