关于指针和数组以及如何在C ++中将它们分配到内存中

时间:2017-01-09 13:36:41

标签: c++ arrays pointers memory-management

所以我试图解决这个问题:

  

数据以以下输入格式输入。第一行包含两个以空格分隔的整数,表示可变长度数组的数量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

基本上,我发现数组地址是重叠的。此外,通过解除引用的答案计算导致意外的输出。对此处所犯错误的任何解释都将受到赞赏。

3 个答案:

答案 0 :(得分:0)

这是一个主要问题:

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

变量col的范围仅在循环内。一旦循环迭代,变量就不复存在了。当您尝试取消引用指针时,存储指向它的指针将导致未定义的行为

简单的解决方案可能是使用colmalloc动态分配内存。

错过了这个问题被标记为C ++,并且因为源实际上没有使用任何特定于C ++的代码而感到困惑。这种情况更糟,因为variable-length arrays不是C ++的一部分。有些编译器将它作为扩展,但在C ++编程时不应该使用它。

相反,您应该使用std::vector,然后您可以在没有自己动态分配的情况下轻松解决问题。然后,您可以row向量intcol向量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;
}