简体   繁体   中英

Trying to dynamically allocate an array inside an element of a vector of structs

I have a vector of point type( point is a structure which contains 2 ints and a pointer to int, s) and I m trying to dynamically allocate memory for the s array( malloc / new) and add two values to it but it gives me seg fault. I don t know if I m allowed to do this inside a vector element. Thank you in advance.

struct point{
    int x, y;
    int *s;
};

int main(void){

    int n, val1, val2, val3, val4, i;
    vector<point> v;

    v.resize(2);
    cin >> n;
    for(i = 1; i <= n; i++)
    {
        cin >> val1 >> val2 >> val3 >> val4;
        v[i - 1].x = val1;
        v[i - 1].y = val2;
        v[i - 1].s = new int[2]; // here i think is the problem.
        //v[i - 1].s = (int *)malloc(2 * sizeof(int));
        v[i - 1].s[0] = val3;
        v[i - 1].s[1] = val4;
    }
    for(i = 0; i <= v.size(); i++)
    {
        cout << v[i].x << " " << v[i].y << " " << v[i - 1].s[0] << " " << v[i - 1].s[1] ;
        cout << "\n";
    }
    return 0;
}
  • You don't resize() the vector to n . You have a fixed value of 2 . This will make the program have undefined behavior as soon as someone enters something larger than 2 in std::cin >> n .
  • The second loop for(i = 0; i <= v.size(); i++) will make the program access v[v.size()] which is out-of-bounds so your program has undefined behavior.
  • The loop for(i = 1; i <= n; i++) isn't wrong since you compensate with i - 1 inside the loop, but it's unnecessary. Do for(i = 0; i < n; i++) or use a range based for-loop (as I'll show below).
  • Don't use new for s . Either use a fixed size std::array<int, 2> or a std::vector<int> that you can resize.

Example:

#include <iostream>
#include <vector>

struct point {
    int x, y;
    std::vector<int> s; // use a vector instead of a raw pointer
};

int main() {   // not main(void)
    int n, val1, val2, val3, val4;
    std::vector<point> v;

    if(!(std::cin >> n)) return 1; // extraction may fail

    v.resize(n); // resize it appropriately

    // you can access the `point`s in the vector using a range based for-loop:
    for(point& p : v) {
        if(std::cin >> val1 >> val2 >> val3 >> val4) { // check if extraction succeeded
            p.x = val1;
            p.y = val2;
            p.s.resize(2);
            p.s[0] = val3;
            p.s[1] = val4;
        } // else /* break, return 1, ... something */
    }

    // You can also access the elements like this, but pay attention
    // to the condition: i < v.size()
    for(int i = 0; i < v.size(); i++) {
        std::cout << v[i].x << ' ' << v[i].y << ' '
                  << v[i].s[0] << ' ' << v[i].s[1] << '\n';
    }
}

Another option is to not resize() v at all and just useemplace_back to add new point s to it. Note how the inner vector , s , gets appropriately sized automatically:

    for(int i = 0; i < n; ++i) {
        if(std::cin >> val1 >> val2 >> val3 >> val4) {
            v.emplace_back(point{val1, val2, {val3, val4}});
        } else
            break;
    }

Also note that accessing vs[0] and vs[1] without checking that it actually has 2 elements is a bit risky, but if you know that's always the case after your initial loop, it should be fine.

This

    v[i - 1].s = new int[2]; // here i think is the problem.
    v[i - 1].s[0] = val3;
    v[i - 1].s[1] = val4;

Is not the problem. The fact that s is a member of an element in a vector is not really relavant. The above is as correct as this:

int* s;
s = new int[2]; // here i think is the problem.
s[0] = val3;
s[1] = val4;

It is a problem, because it is not clear why you want to use a manually allocated array here. I am always a bit puzzled when I see std::vector and new int[2] in the same code. From a vector you get all you can get from a dynamically allocated array and more. Anyhow the problem causing the segfault is elsewhere...

v.resize(2);
cin >> n;
for(i = 1; i <= n; i++)
{
    cin >> val1 >> val2 >> val3 >> val4;
    v[i - 1].x = val1;
    ....

v has 2 elements. Nowhere in your code the number of elements changes. When the user enters anything bigger than 2 for n you will access the vector out of bounds. Out of bounds access is undefined behavior. Anything could happen when you run the code.

Also your last loop is wrong. The last valid index is v.size()-1 . It is common to use half open intervals, ie the start is included, end not:

 for(i = 0; i < v.size(); i++)
         //   ^^ not <= !!!

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