如何在使用动态2D数组时修复此代码

时间:2019-03-24 06:32:45

标签: c++ pointers

我正在使用动态2D数组,并且需要特定索引的值,但是它无法打印正确的值。

```int u=5;//No. of elements
int S[u];
int i=0;
while(i<u)//elements in universal set
{
    cin>>S[i];
    i++;
}
int n;
cin>>n;//no. of subset
i=0;
int subcost[n];
int **subset;
subset=new int*[n];
while(i<n)
{
    int l,c;
    cin>>l;//size of ith subset
    subset[i]=new int[l];
    int j=0;
    while(j<l)//Elements in each subset
    {
        cin>>subset[i][j];
        j++;
    }
    cin>>c;//cost for each subset
    subcost[i]=c;
    i++;
}

i=0;
while(i<n)
{
    int j=0;
    int s=*subset[i];
    while(j<s)
    {
        cout<<subset[i][j]<<"\n";
        j++;
    }
    i++;
}```

我希望输出是每个子集的值,但是实际输出却完全不同。

3 个答案:

答案 0 :(得分:0)

arr[i]=new int[n1];

new的操作存在误解。 (也许您来自Java?)这不会存储值为n1的整数。而是创建一个大小为n1的数组。

一个指针级别对于一个数组就足够了

int n = 5;
int i = 0;

int *arr;
arr = new int[n];
arr[i] = 100;

cout << arr[i] << endl;  // output: 100


delete[] arr;  // remember to deallocate – otherwise memory leaks will haunt your system!

如果您正在寻找2D数组,则指向指针(**)的指针将起作用。

int **arr;
arr = new int[n];       //
arr[0] = new int[n];    //  allocate first array
arr[0][0] = 100;        //  set first element of first array

delete[] arr[0];
delete[] arr;           //  deallocate

答案 1 :(得分:0)

这里

arr[i]=new int[n1]; /* allocating memory for arr[i], equal to n1*sizeof(int) bytes & arr[i] gets points to address returned by new */
cout<<"Value of "<<i<<"th row is :- "<<arr[i]<<"\n";
  

我希望输出为n1的值,但实际输出为 some   随机地址

是的,arr[i]是动态创建的数组并打印,它将仅打印其基址。

请尝试在此版本中尝试解释注释中的代码更改。

int main(void) {
    std::cout<<"Enter the value of n"<<"\n";
    int n;
    std::cin>>n;
    int **arr;
    /* allocate memory for arr. arr holds base address of array of n int ptr */
    arr=new int*[n];
    int i=0;
    int n1;
    std::cout<<"Enter the value of n1"<<"\n";
    std::cin>>n1;
    /* allocate memory for arr[0], arr[1] .. */
    while(i < n1) {
        arr[i]=new int[n1];
        i++;
    }
    /* put the data into dynamically allocated array */
    for(int row = 0; row < n; row++) {
        for(int col = 0; col < n1; col++) {
            std::cin>>arr[row][col];
        }
    }
    /* printh te data */
    for(int row = 0; row < n; row++) {
        for(int col = 0; col < n1; col++) {
            std::cout<<"Value of "<<i<<"th row is :- "<<arr[row][col];
        }
        std::cout<<"\n";
    }
    return 0;
}

由于使用new创建了动态数组,因此需要释放动态分配的内存以避免内存泄漏,因此请相应地使用delete运算符。

如其他人所指出的,std::vector比上面的更好。

答案 2 :(得分:0)

虽然@Achal为动态分配提供了一个很好的答案,但是如上所述,您确实应该使用C ++提供的容器vector来使事情变得更加轻松和健壮。所有C ++容器都提供了自动内存管理功能,使您不必手动分配内存(并且出错的几率很小)

在使用容器(例如向量的向量)存储数据时,您可以简单地读取和丢弃"//elements in universal set""//no. of subset""//Elements in each subset"。使用容器时,不需要这些值。您只需读取所需的值并将其添加到容器中,容器就会根据需要增长。

虽然不是100%清楚您的输入数据是什么样子,但我们可以从您的文件中推断出它是什么样子:

示例输入文件

您的第一个整数是"//elements in universal set",不需要读取数据。同样,第二行,您的"//no. of subset"与读取数据无关。最后,也不需要每个数据行上的第一个元素"//Elements in each subset"。只需读取并丢弃这些值中的每一个即可得出最终数据集。

$ cat dat/universal_sub.txt
5
4
5 1 2 3 4 5
3 1 2 3
4 1 2 3 4
6 1 2 3 4 5 6

您要存储的最终数据集

从完整文件来看,这些似乎是您要存储的实际数据值(可以有偶数,但没有要求)

1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6

有很多不同的方法可以将这些片段组合在一起。关于如何从输入文件中获取最终数据集的一个简短示例可能是:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <limits>

int main (void) {

    std::string line;                       /* string for reading each line */
    std::vector<std::vector <int>> subset;  /* vector<vector<int>> */
    int universal, nsubsets;                /* two int to read/discard */

    if (!(std::cin >> universal >> nsubsets)) { /* read/dicard 2 values */
        std::cerr << "error: failed to read universal.\n";
        return 1;
    }
    /* read/discard '\n' (any chars) left in input buffer line by cin above */
    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');

    while (getline (std::cin, line)) {  /* read each remaining data line */
        int unneeded, i;                /* 1st value and i for rest */
        std::vector<int> tmp;           /* vector<int> for each line */
        std::stringstream ss (line);    /* stringstream to read from */
        if (ss >> unneeded) {           /* read/discard 1st value */
            while (ss >> i)             /* read rest from stringstream */
                tmp.push_back(i);       /* add to tmp vector */
            subset.push_back(tmp);      /* add tmp vector to subset */
        }
    }

    for (auto& i : subset) {        /* loop over subsets */
        for (auto& j : i)           /* loop over each value in subset */
            std::cout << " " << j;  /* output value */
        std::cout << '\n';          /* tidy up with newline */
    }
}

注意:,输出循环使用Range-based for loop (since C++11),但您可以将.begin().end()容器函数与传统的{{ 1}},如果您的编译不支持for

大量使用/输出

将数据读入向量的载体中可以访问每个元素:

std=c++11

仔细检查一下,如果您还有其他问题,或者我对数据文件格式的理解不正确,请告诉我。