Passing 2d dynamic array to function.

Hi, I have a 2d dynamic array filled with numbers I read in from a file. I printed the array in main to verify it was good, and it was. I am trying to pass that dynamic 2d array into a function and print it out in the function(I'll eventually do more with it, but just print for now), but it just prints out zeroes. Can someone tell me where I messed up please?

Thank you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void calculateAverage(int **arr, int x, int y){
    
    // edit ** 
   // for (int i=0; i<x; ++i) {
        
     //   arr[i] = new int [y]; 
        
   // } 
   // these lines weren't needed. Works if removed
  // /edit
    
    for (int i = 0; i < x; i++){
        
        for (int j = 0; j < y; j++){
            
            cout << arr[i][j] << " " ;
            
        }
        
    cout << endl;
    
    }
    
}


int main (){

    int row;
    int col;
    
    int** grades;
    string* names;
    
    
    string file = "kids_menu.txt";
    ifstream loadFile;

    loadFile.open(file.c_str());
    
    loadFile >> row;
    loadFile.get();
    loadFile >> col;
    loadFile.get();
    
    grades = new int*[row];
    names = new string[row];

    for (int i = 0; i < row; i++) {

        grades[i] = new int[col];

    }
    
    int i = 0;
    loadFile >> names[i];
    loadFile.get();
    
    while(loadFile){
        
        for (int j = 0; j < col; j++){

            loadFile >> grades[i][j];
            loadFile.get();
            
        }
        
        i++;
        loadFile >> names[i];
        loadFile.get();
        
    }
    
    calculateAverage(grades, row, col); // here is where I call it
    
    loadFile.close();
    
}

     
Last edited on
You didn't just pass it to the function ... you tried to allocate yet more memory to the pointers in that function (lines 9-13). Hard to see why.
That was unintentional. I thought that was how you passed them to functions.

edit**

Ohhhhhh. Just remove those lines.

It works. Thank you. haha
Last edited on
Please post a small sample of your input file.

Why are you using arrays (parallel arrays at that) instead of std::vector of some structure?

I can post the entire file. It is very small.

6 5
Bob 86 77 98 67 79
Chris 89 67 78 64 72
Jen 65 86 63 90 70
John 92 87 84 79 81
Josh 89 95 77 72 70
Tom 77 70 68 81 69

I'm just going with what I know. Vectors are a very weak topic for me.
Vectors are a very weak topic for me.

You could save yourself a lot of grief if you made an effort to learn using them.

Passing a 2D vector requires only 1 parameter, not the 3 for a C style array:

void calculateAverage(std::vector<std::vector<int>>& vec);

The number of rows and columns in your 2D vector are automatically available within the function.

Dealing with 2D containers can be really easy when using range-based for loops:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector>

void Print2DVector(std::vector<std::vector<int>>&);

int main()
{
   std::vector<std::vector<int>> grades { { 86, 77, 98, 67, 79 },
                                          { 89, 67, 78, 64, 72 },
                                          { 65, 86, 63, 90, 70 },
                                          { 92, 87, 84, 79, 81 },
                                          { 89, 95, 77, 72, 70 },
                                          { 77, 70, 68, 81, 69  } };

   Print2DVector(grades);
}


void Print2DVector(std::vector<std::vector<int>>& vec)
{
   for (auto& rows : vec)
   {
      for (auto& cols : rows)
      {
         std::cout << cols << ' ';
      }
      std::cout << '\n';
   }
}

86 77 98 67 79
89 67 78 64 72
65 86 63 90 70
92 87 84 79 81
89 95 77 72 70
77 70 68 81 69


With a couple of templated overloads of std::ostream operator<<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      os << x << '\n';
   }

   return os;
}


template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for (auto const& x : v)
   {
      os << x << ' ';
   }

   return os;
}


makes writing out a 1D or 2D vector is as easy as:

std::cout << grades << '\n';

Why templates? So you don't have to code separate functions for each data type, such as int, char or even std::string.

Passing a 2D vector requires only 1 parameter, not the 3 for a C style array:


Actually if a structure/class were used you would only need a single dimensional vector/array.

1
2
3
4
5
6
7
8
9
10
11
12
...
struct Student
{
     std::string name;
     std::vector<int> grades;
}

int main()
{
    std::vector<Student> students;

...


By the way if you use vectors you also don't need to first two entries in your file.

Also your current "read" of the file, you don't need all of those get() calls, the insertion operator skips leading whitespace by default.

You may also want to consider using a stringstream, retrieve a complete line into a string with getline() then use the stringstream to process that line.

Vectors is a topic coming up later in the semester, so I might as well take advantage of the vector course this thread has become. This is great info y'all. I have it favorited for future reference.

How would a file be read into a vector?

In >>
std::vector<Student> students;

Can strings and ints both go into that vector or just ints since that's the vector in the struct is <int>?
How would a file be read into a vector?

Depends on how the data is laid out in the file.

Based on your data file make a struct that contains a string and 5 shorts.

Read each line using std::getline after the first into a temp string and then parse out the individual data elements, shoving each in turn into a temp struct variable.

When you've filled out the struct elements insert/push back it into the vector.

Lather, Rinse, Repeat until you've read all the data lines or read the indicated amount of data.

Crude, brute force, but it would work.
Topic archived. No new replies allowed.