-1

I've recently started learning coding in the C++ language, and am having issues grasping the concept of pointers in C++.

I'm trying to practice dynamic memory allocation but keep running into errors when trying to compile my program.

Here are some struct objects I've created along with some global variables outside of my main function:

// Storing x and y values from file
struct gridSize {
    int gridXValue;
    int gridYValue;
    
    string toString();
};

string gridSize::toString ()
{
    ostringstream oss;

    oss << "gridXValue : " << gridXValue << endl;
    oss << "gridYValue : " << gridYValue << endl;

    return (oss.str());
}

// Storing details for each grid area within
// 2D array struct
struct grid_area {
    int x, y;
    bool is_occupied;
    int city_id;
    string city_name;
    int cloud, cloud_index, pressure, pressure_index;
    char cloudcover_LMH, pressure_LMH;
};

gridSize gridSize; //Global struct object
grid_area *ga = nullptr; //Global pointer variable

Here is what my main function looks like:

int main ()
{
    int userChoice;

    // Main menu to run constantly until user enters 8
    while (userChoice != 8) {
        cout << "Welcome to Weather Information Processing System!" << endl;
        cout << "-------------------------------------------------" << endl;

        cout << endl;

        cout << "1)\tRead in and process a configuration file" << endl;
        cout << "2)\tDisplay city map" << endl;
        cout << "3)\tDisplay cloud coverage map (cloudiness index)" << endl;
        cout << "4)\tDisplay cloud coverage map (LMH symbols)" << endl;
        cout << "5)\tDisplay atmospheric pressure map (pressure index)" << endl;
        cout << "6)\tDisplay atmospheric pressure map (LMH symbols)" << endl;
        cout << "7)\tShow weather forecast summary report" << endl;
        cout << "8)\tQuit" << endl;

        cout << endl;

        cout << "Please enter your choice: ";
        cin >> userChoice;

        cout << endl;

        if (userChoice == 1) {
            // Process all files
            readAFile();
        }
    }
        
        // Deallocate memory for 2D array
        for (int i = 0; i < gridSize.gridXValue + 1; i++) 
        {
            delete[] ga[i];
        }
        delete[] ga;
        
    
    return (0);
}

I highly suspect the issue lies in the last few portions of my readAFile function, but am unable to identify the problem. Here's the portion where I suspect the problem lies in readAFile:

    // Allocate array memory
    ga = new grid_area [gridSize.gridXValue + 1];
    for (int i = 0; i < gridSize.gridYValue + 1; i++)
        ga[i] = new grid_area[gridSize.gridYValue + 1];

    // Putting x and y values into  array
    for (int x_array = 0; x_array < gridSize.gridXValue + 1; x_array++) {
        for (int y_array = 0; y_array < gridSize.gridYValue + 1; y_array++) {
            ga[x_array][y_array].x = x_array;
            ga[x_array][y_array].y = y_array;
        }
    }

This is error I'm getting:

csci251_a1.cpp: In function ‘int main()’:
csci251_a1.cpp:110:20: error: type ‘struct grid_area’ argument given to ‘delete’, expected pointer
       delete[] ga[i];
                    ^
csci251_a1.cpp: In function ‘void readAFile()’:
csci251_a1.cpp:172:54: error: no match for ‘operator=’ (operand types are ‘grid_area’ and ‘grid_area*’)
         ga[i] = new grid_area[gridSize.gridYValue + 1];
                                                      ^
csci251_a1.cpp:32:8: note: candidate: ‘grid_area& grid_area::operator=(const grid_area&)’
 struct grid_area {
        ^~~~~~~~~
csci251_a1.cpp:32:8: note:   no known conversion for argument 1 from ‘grid_area*’ to ‘const grid_area&’
csci251_a1.cpp:32:8: note: candidate: ‘grid_area& grid_area::operator=(grid_area&&)’
csci251_a1.cpp:32:8: note:   no known conversion for argument 1 from ‘grid_area*’ to ‘grid_area&&’
csci251_a1.cpp:177:24: error: no match for ‘operator[]’ (operand types are ‘grid_area’ and ‘int’)
             ga[x_array][y_array].x = x_array;
                        ^
csci251_a1.cpp:178:24: error: no match for ‘operator[]’ (operand types are ‘grid_area’ and ‘int’)
             ga[x_array][y_array].y = y_array;

I really don't understand what I'm doing wrong here... If needed, I can provide the rest of the readAFile function as well. Any help would be greatly appreciated.

Zeffia
  • 37
  • 5
  • 2
    *I'm trying to practice dynamic memory allocation but keep running into errors when trying to compile my program.* -- `grid_area *ga = nullptr;` -- In the tutorials or books you have seen that allocate a 2D array dynamically, did they declare a pointer with only 1 `*`? Edging towards closing this as a typo... – PaulMcKenzie Jan 27 '22 at 18:31
  • Why do you think you need to deallocate each element of ga? Have you read what `delete[]` does? – Incomputable Jan 27 '22 at 18:31
  • `ga[i]` is not a pointer, it tells you. `ga` is an array of `struct`s – littleadv Jan 27 '22 at 18:31
  • @PaulMcKenzie am I not supposed to declare a pointer with only 1 *? That's what I've learnt... I tried adding an additional * and the error message I get now is drastically shorter: `error: cannot convert ‘grid_area*’ to ‘grid_area**’ in assignment ga = new grid_area [gridSize.gridXValue + 1]; ` – Zeffia Jan 27 '22 at 18:42
  • @Zeffia *That's what I've learnt* -- C++ is a language where you just can't simply "do your own thing" and learn without seeing proper examples. I can guarantee that every example of dynamic 2D array creation using a pointer (unless it's a flattened 2D array) will show the declaration using 2 `*`, i.e. double pointer. That's why I was inclined to close this as a typo, as it would be very difficult to make this mistake, given that every example shows how to do this correctly. So yes, that's how you declare a pointer whos purpose will ultimately point to a dynamically allocated 2D array. – PaulMcKenzie Jan 27 '22 at 18:45
  • A common 2D array implementation, and the one it looks like you're implementing, consist of 1 Array of N pointers to N arrays of M data elements. it will look like `grid_area ** ga;`. In English, `ga` is a pointer (the first `*`) to one or more pointers ( the second `*`) to one or more `grid_area `s. – user4581301 Jan 27 '22 at 18:48
  • @Zeffia [See this](https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new). Look at the highest rated answer, and the second part of that answer starting with `Otherwise`. Then [see this](https://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c/21944048#21944048) to get an idea of how to create the items efficiently in contiguous memory. – PaulMcKenzie Jan 27 '22 at 18:54
  • @PaulMcKenzie I see. That was very helpful and informative. Using `ga = new grid_area * [gridSize.gridXValue + 1];` instead was what solved everything! Thanks! – Zeffia Jan 27 '22 at 19:04

1 Answers1

0

I should have used a point-to-pointer variable instead of a regular pointer variable for a dynamic 2D array.

Instead of:

grid_area *ga = nullptr;

It should be:

grid_area **ga = nullptr;

And,

ga = new grid_area [gridSize.gridXValue + 1];

Should be:

ga = new grid_area *[gridSize.gridXValue + 1];

Admittedly, I probably should have searched up some more actual examples before hastily posting a question. Thanks to every one who responded!

Zeffia
  • 37
  • 5