簡體   English   中英

關於指針和數組以及它們如何在 C++ 中的內存中分配

[英]Regarding pointers and arrays and how they are assigned in memory in C++

所以我試圖解決這個問題:

數據以以下輸入格式輸入。 第一行包含兩個空格分隔的整數,表示可變長度數組的數量n和查詢的數量q 后續行的每一行都包含一個以空格分隔的序列,格式為

k A i [0] A i [1] … A i [k-1]

其中k是數組的長度A i ,后跟A ik 個元素。 隨后的每一行都包含兩個以空格分隔的整數,用於描述查詢的數組編號(范圍從0 到 n-1 )和該特定數組中的索引(范圍從0 到 k i )的相應值。 即,給定以下輸入:

3 3
3 1 2 3
5 4 5 6 7 8
4 9 10 11 12 
0 1
1 3
2 0

這個輸出是預期的

2
7
9

我基本上是 C++ 的初學者。 這是我嘗試過的代碼,但我覺得存儲每個后續數組的地址給我帶來了一些問題

int main(){
    int n, q;
    scanf("%d %d", &n, &q);
    printf("n,q = %d, %d\n", n, q);
    int* row[n];
    for (int i = 0; i < n; i++){
        int k;
        scanf("%d", &k);
        printf("k = %d\n", k);
        int col[k];
        row[i] = col;
        for (int j = 0; j < k; j++){
            int elem;
            scanf("%d", &elem);
            printf("i,j,elem = %d, %d, %d\n", i, j, elem);
            col[j] = elem;
            cout << "address is " << &(col[j]) << "\n";
        }
    }
    for (int query = 1; query <= q; query++){
        int i, j;
        scanf("%d %d", &i, &j);
        int answer;
        answer = *(row[i] + j);
        printf("row[%d][%d] is %d\n", i, j, answer);
        cout << "address is " << &answer << "\n";
    }
    return 0;
}

這是產生的輸出:

n,q = 3, 3
k = 3
i,j,elem = 0, 0, 1
address is 0x7ffe236edb70
i,j,elem = 0, 1, 2
address is 0x7ffe236edb74
i,j,elem = 0, 2, 3
address is 0x7ffe236edb78
k = 5
i,j,elem = 1, 0, 4
address is 0x7ffe236edb60
i,j,elem = 1, 1, 5
address is 0x7ffe236edb64
i,j,elem = 1, 2, 6
address is 0x7ffe236edb68
i,j,elem = 1, 3, 7
address is 0x7ffe236edb6c
i,j,elem = 1, 4, 8
address is 0x7ffe236edb70
k = 4
i,j,elem = 2, 0, 9
address is 0x7ffe236edb60
i,j,elem = 2, 1, 10
address is 0x7ffe236edb64
i,j,elem = 2, 2, 11
address is 0x7ffe236edb68
i,j,elem = 2, 3, 12
address is 0x7ffe236edb6c
row[0][1] is 32766
address is 0x7ffe236edbcc
row[1][3] is 32766
address is 0x7ffe236edbcc
row[2][0] is 3
address is 0x7ffe236edbcc

基本上,我發現數組地址是重疊的。 此外,通過取消引用進行的答案計算會導致意外的輸出。 對此處所犯錯誤的任何解釋將不勝感激。

這里有一個主要問題:

for (int i = 0; i < n; i++){
    ...
    int col[k];
    row[i] = col;
    ...
}

變量col僅在循環內有其作用域。 一旦循環迭代,變量就不再存在。 當您嘗試取消引用指針時,存儲指向它的指針將導致未定義的行為

簡單的解決方案可能是使用malloccol動態分配內存。


錯過了該問題被標記為 C++,並感到困惑,因為源代碼實際上並未使用任何特定於 C++ 的代碼。 這種情況更糟,因為可變長度數組不是 C++ 的一部分。 一些編譯器將它作為擴展,但在用 C++ 編程時不應該使用它。

相反,您應該使用std::vector ,然后您無需自己的動態分配即可輕松解決問題。 然后,您可以使row成為int向量的向量,將col設為int向量,然后分配將正常工作(當然,如果row已設置為正確的大小)。

使用 C++ 而不會出現太多內存管理錯誤的一種簡單方法是使用標准庫類型。 把裸機的東西留給那些沒有那些東西的可憐的 C 人;)

因此,不要干預new[]delete[] ,而是使用std::vector<>類的類型。

下面的“現代 C++”版本無緣無故地使用 iostream。 舊的stdio.h有時是首選,有時也是iostream 有時這只是風格和品味的問題。

#include <vector>
#include <iostream>
#include <fstream>

typedef struct Q
{
    int iArray;
    int iIndex;
} Q_t;

typedef std::vector<std::vector<int> > Data_t;
typedef std::vector<Q_t> Query_t;

bool Load(Data_t& data, Query_t &queries, std::istream& is)
{
    size_t ndata = 0;
    size_t nqueries = 0;
    is >> ndata;
    is >> nqueries;
    data.resize(ndata);
    queries.resize(nqueries);

    for (size_t d = 0; d < ndata; d++)
    {
        size_t l = 0;
        is >> l;
        data[d].resize(l);
        for (size_t i = 0; i < l; i++)
        {
            is >> data[d][i];
        }
    }

    for (size_t q = 0; q < nqueries; q++)
    {
        is >> queries[q].iArray;
        is >> queries[q].iIndex;
    }
    return true;
}


int main(int argc, const char * argv[])
{
    std::ifstream input("E:\\temp\\input.txt");
    Data_t data;
    Query_t queries;
    if (Load(data, queries, input))
    {
        for (auto &q : queries)
        {
            std::cout << data[q.iArray][q.iIndex] << std::endl;
        }
    }
    return 0;
}

錯誤是,您使用了'col' 數組,它在 for 循環完成后失去了其作用域。 解決此問題的方法是使用動態內存分配在 for 循環之外聲明它

希望下面的代碼能幫助你得到一個想法:)

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
    int n, q;
    cin >> n;
    cin >> q;
    int* row[n];
    int* col;
    for(int i=0; i<n; i++)
    {
        int k;
        cin >> k;
        col = new int[k];
        row[i] = col;
        for(int j=0; j<k; j++)
        {
            cin >> col[j];
        }
    }
    for(int query=0; query<q; query++)
    {
        int i,j;
        cin >> i;
        cin >> j;
        cout << row[i][j] << endl;
    }
delete[] col;
    return 0;
}

暫無
暫無

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

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