Setting class level 2D Array variable to passed in value - C++

一世执手 提交于 2019-12-24 12:00:54

问题


I'm attempting to make a maze-solving program, and while the algorithm is sound (at least in my head), I've been running into a roadblock with 2D arrays. I'm coming from C# and Java, so the syntax is giving me grief.

Here's an SSCCE:

//Main.cpp

#include "MazeSolver.h"

int main()
{
     MazeSolver mazeSolver;

     char maze[51][51] = { }; // Not bothering to show code for populating the array

     mazeSolver.setMaze(maze);
}

//MazeSolver.cpp

#include "MazeSolver.h"

MazeSolver::MazeSolver() { }

void MazeSolver::setMaze(char maze[51][51])
{
     this->maze = maze;
}

//MazeSolver.h

#ifndef _MAZESOLVER_H
#define _MAZESOLVER_H

class MazeSolver
{
private:
     char **maze; // This is likely the problem, I'm at wits end in regards to
                  // what notation is needed here.  I do not want to hard-copy
                  // the entire array, I just need to access it (via pointer)
                  // I've also tried just using char maze[51][51] here, char *maze, etc...
public:
      MazeSolver();
      void setMaze(char maze[51][51]);
}

回答1:


<rant>

This is one of the weird quirks of C++.

C++ 2D arrays are NOT jagged arrays. When you declare char maze[51][51], it actually allocates 1 contiguous array 51*51 members long. sizeof(maze) == 51*51. When you dereference a value, maze[a][b], what it actually does is *(maze+51*a+b). All this is under the hood.

A Jagged Array is an array of arrays, a char**. In this case, you have an array of 51 pointers size == (51*sizeof(void*)). In each position, the pointer points to a completely different memory location, allocated to 51 members long.

This is ANNOYING because you can't just convert the two, even by casting. You have to deal with weird syntax, such as char (*maze)[51] to get a pointer to the 2D array.

Whats even more annoying is the following happens:

int foo(int maze[51][51])
{
   return sizeof(maze);
}

int maze[51][51];

int main(int argc, char** argv)
{
   std::cout << sizeof(maze) << std::endl;//return 51*51*sizeof(int);
   std::cout << foo(maze) << std::endl;//return 8, sizeof(void*);
}

So it implicitly passes by reference, not by value, which is opposite all the rest of C++.

</rant>

tl;dr;

The correct syntax for a pointer to a 2D array is char (*maze)[51];. Your syntax is for a jagged array (arrays of arrays) which is NOT the same thing in C++.




回答2:


You cant assign (Or convert) 2d arrays (array[ROWS][COLUMNS]) to pointers to pointers (aka **) because the memory layout of a 2d array is (could be) very different to the memory layout the pointer of pointers could point to.

Check this thread for more info about this topic.

If suggest you to use the de facto C++ standard container, std::vector, instead of a plain array:

class MazeSolver
{
    std::vector<std::vector<char>> maze;

    void setMaze( const std::vector<std::vector<char>>& new_maze )
    {
        maze = new_maze;
    }
};

Note that a vector has size 0 by default (At the point of its initialization), so you should fill it with elements:

for( std::size_t i = 0 i < ROWS ; ++i )
{
    maze.push_back( std::vector<char>() );

    for( std::size_t j = 0 ; j < COLUMNS ; ++j )
       maze[i].push_back( ' ' );
}

However, C++11 (The current iteration of the language) has a std::array container which is like a C array but with the interface of other Standard Library Containers:

std::array<char,ROWS*COLUMNS> maze;


来源:https://stackoverflow.com/questions/21680677/setting-class-level-2d-array-variable-to-passed-in-value-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!