所以我试图解决这个问题:
数据以以下输入格式输入。第一行包含两个以空格分隔的整数,表示可变长度数组的数量
的空格分隔序列n
和查询数q
。后续行的每一行都包含格式为k A i [0] A i [1] ... A i [k-1]
其中 k 是数组的长度, A i ,后跟 k 元素 A i 。每个后续行包含两个空格分隔的整数,用于描述数组编号的相应值(范围从 0到n-1 )和该特定数组中的索引(范围从 0到k < sub> 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
基本上,我发现数组地址是重叠的。此外,通过解除引用的答案计算导致意外的输出。对此处所犯错误的任何解释都将受到赞赏。
答案 0 :(得分:0)
这是一个主要问题:
for (int i = 0; i < n; i++){
...
int col[k];
row[i] = col;
...
}
变量col
的范围仅在循环内。一旦循环迭代,变量就不复存在了。当您尝试取消引用指针时,存储指向它的指针将导致未定义的行为。
简单的解决方案可能是使用col
为malloc
动态分配内存。
错过了这个问题被标记为C ++,并且因为源实际上没有使用任何特定于C ++的代码而感到困惑。这种情况更糟,因为variable-length arrays不是C ++的一部分。有些编译器将它作为扩展,但在C ++编程时不应该使用它。
相反,您应该使用std::vector
,然后您可以在没有自己动态分配的情况下轻松解决问题。然后,您可以row
向量int
和col
向量int
向量,然后分配将正常工作(如果已row
当然,设置为正确的大小。)
答案 1 :(得分:0)
使用C ++而不会获得太多内存管理错误的简单方法是使用标准库类型。把剩下的金属东西留给那些没有那个的穷人;)
因此,不要干涉new[]
和delete[]
,而应使用类似std::vector<>
的类型。
&#34;现代C ++&#34;以下版本使用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;
}
答案 2 :(得分: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;
}