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

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

我有一个点类型的向量(点是一个包含 2 个整数和一个指向整数 s 的指针的结构),我正在尝试为 s 数组动态分配内存(malloc / new)并添加两个值到它,但它给了我段错误。我不知道是否允许我在矢量元素内执行此操作。提前谢谢你。

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;
}
  • 您不会 resize() vectorn。您的固定值为 2。一旦有人在 std::cin >> n.
  • 中输入大于 2 的内容,这将使程序具有未定义的行为
  • 第二个循环 for(i = 0; i <= v.size(); i++) 将使程序访问 v[v.size()],即 out-of-bounds,因此您的程序具有未定义的行为。
  • 循环 for(i = 1; i <= n; i++) 并没有错,因为你在循环内用 i - 1 进行了补偿,但这是不必要的。执行 for(i = 0; i < n; i++) 或使用基于 for-loop 的范围(如下所示)。
  • 不要将 new 用于 s。使用固定大小 std::array<int, 2> 或可以调整大小的 std::vector<int>

示例:

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

另一种选择是 resize() v 并且只使用 emplace_back 添加新的 point 到它。请注意内部 vectors 如何自动调整大小:

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

另请注意,访问 v.s[0]v.s[1] 而不检查它是否确实具有 2 元素有点冒险,但如果您 知道 初始循环后总是这样,应该没问题。

这个

    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;

不是的问题。 s 是向量中元素的成员这一事实并不真正相关。以上是正确的:

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

a的问题,因为不清楚为什么要在这里使用手动分配的数组。当我在同一段代码中看到 std::vectornew int[2] 时,我总是有点疑惑。从向量中,您可以获得动态分配的数组所能获得的一切等等。无论如何,导致段错误的问题在其他地方......

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

v 有 2 个元素。在您的代码中,元素的数量没有任何变化。当用户为 n 输入大于 2 的值时,您将越界访问向量。越界访问是未定义的行为。当您 运行 代码时,任何事情都可能发生。

你最后一个循环也是错误的。最后一个有效索引是 v.size()-1。通常使用半开区间,即包含开始,不包含结束:

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