user51966
user51966

Reputation: 1057

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

Upvotes: 1

Views: 481

Answers (2)

javaLover
javaLover

Reputation: 6425

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

Upvotes: 1

R Sahu
R Sahu

Reputation: 206667

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);

Upvotes: 2

Related Questions