简体   繁体   English

尝试在结构向量的元素内动态分配数组

[英]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.我有一个点类型的向量(点是一个包含 2 个整数和一个指向 int, s 的指针的结构),我正在尝试为 s 数组(malloc / new)动态分配内存并向其添加两个值,但它给出我错了。 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 .你不resize() vectorn You have a fixed value of 2 .您有一个固定值2 This will make the program have undefined behavior as soon as someone enters something larger than 2 in std::cin >> n .一旦有人在std::cin >> n输入大于2 ,这将使程序具有未定义的行为。
  • 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.第二个循环for(i = 0; i <= v.size(); i++)将使程序访问v[v.size()]越界,因此您的程序具有未定义的行为。
  • The loop for(i = 1; i <= n; i++) isn't wrong since you compensate with i - 1 inside the loop, but it's unnecessary. for(i = 1; i <= n; i++)循环没有错,因为你在循环内用i - 1补偿,但这是不必要的。 Do for(i = 0; i < n; i++) or use a range based for-loop (as I'll show below).执行for(i = 0; i < n; i++)或使用基于范围的 for 循环(如下所示)。
  • Don't use new for s .不要对s使用new Either use a fixed size std::array<int, 2> or a std::vector<int> that you can resize.使用固定大小的std::array<int, 2>或可以调整大小的std::vector<int>

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.另一种选择是根本不resize() v ,只需使用emplace_back向其添加新point s 。 Note how the inner vector , s , gets appropriately sized automatically:请注意内部vector s如何自动获得适当大小的:

    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.还要注意,访问vs[0]vs[1]而不检查它实际上有2元素是有点冒险的,但是如果您知道在初始循环之后总是这种情况,那应该没问题。

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. s是向量中元素的成员这一事实并不是真正相关的。 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.当我在同一代码中看到std::vectornew int[2]时,我总是有点困惑。 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. v有 2 个元素。 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.当用户为n输入大于 2 的任何值时,您将越界访问向量。 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 .最后一个有效索引是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 <= !!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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