[英]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 i的k 個元素。 隨后的每一行都包含兩個以空格分隔的整數,用於描述查詢的數組編號(范圍從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
僅在循環內有其作用域。 一旦循環迭代,變量就不再存在。 當您嘗試取消引用指針時,存儲指向它的指針將導致未定義的行為。
簡單的解決方案可能是使用malloc
為col
動態分配內存。
錯過了該問題被標記為 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.