簡體   English   中英

嘗試在結構向量的元素內動態分配數組

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

我有一個點類型的向量(點是一個包含 2 個整數和一個指向 int, 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()]越界,因此您的程序具有未定義的行為。
  • for(i = 1; i <= n; i++)循環沒有錯,因為你在循環內用i - 1補償,但這是不必要的。 執行for(i = 0; i < n; i++)或使用基於范圍的 for 循環(如下所示)。
  • 不要對s使用new 使用固定大小的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 s 。 請注意內部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;
    }

還要注意,訪問vs[0]vs[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;

這是一個問題,因為不清楚為什么要在這里使用手動分配的數組。 當我在同一代碼中看到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 <= !!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM