Anton Boritskiy
Anton Boritskiy

Reputation: 1569

C++ pass array argument to a function

I want to pass a reference to an array from one object GameModel to another PersonModel, store reference and then work with this array inside PersonModel just like inside GameModel, but...

I have a terrible misunderstanding of passing an array process: In the class PersonModel I want to pass an array by reference in a constructor (see code block below). But the marked line throws the compile error

    PersonModel::PersonModel( int path[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel ) { 
        this->path = path; //<------ ERROR here:
        //PersonModel.cpp:14:22: error: incompatible types in assignment of 'int (*)[30]' to 'int [31][30]'

        this->permissionLevel = permissionLevel;
    }

Here is the header file PersonModel.h

#ifndef PERSON_MODEL
#define PERSON_MODEL

#include "data/FieldSize.h"

namespace game{
    class IntPosition;
    class MotionDirection;

    class PersonModel {
        protected:
        int path[FieldSize::HEIGHT][FieldSize::WIDTH];
        int permissionLevel;

        public:
        PersonModel( int path[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel );
        void setMotionDirection ( MotionDirection* md);
        void step(long time);
        void reset(long time);
    };
}

#endif 

As I see now, I can change the int path[FieldSize::HEIGHT][FieldSize::WIDTH]; declaration to int (*path)[FieldSize::WIDTH]; but it is much more confusing.

Help me understand this topic: what is the proper way to store the passed reference to an array to work with it later, like with usual 2D array.

UPDATE:

This array is a map of game field tiles properties represented by bit-masks, so it is read-only actually. All the incapsulated objects of GameModel class should read this array, but I definitely don't want to duplicate it or add some extra functionality.

There are no frameworks just bare Android-NDK.

Upvotes: 0

Views: 769

Answers (6)

Moamen
Moamen

Reputation: 11

the name of the array is a pointer on first element so, you can try

PersonModel( int (*path)[FieldSize::HEIGHT][FieldSize::WIDTH], int permissionLevel );

Upvotes: 0

bobestm
bobestm

Reputation: 1334

You would have to pass a pointer to the 2d-array as you cannot pass the array as you have stated in the code snippet. I would suggest using the STL array type. Admittedly std::array is C++ '11 standard and therefore old compiler may not support it. You can also use vector which has been around longer.

vector<vector<int>>path;

You will have to resize the 2d-vector in the constructor. Indexing would look a bit funny:

path[1].[1] ....

With vectors, you can then pass it by reference.

Upvotes: 0

Roddy
Roddy

Reputation: 68074

I think you've fallen into the classic trap of believing someone who's told you that "arrays and pointers are the same in C".

The first thing I'd do would be to define a type for the array:

typedef int PathArray[FieldSize::HEIGHT][FieldSize::WIDTH];

You then don't need to worry about confusions between reference to array of ints vs array of references to ints.

Your PersonModel then contains a reference to one of these.

PathArray &path;

and, because its a reference it must be initialised in the constructors initialization list rather than in the constructor body.

 PersonModel::PersonModel( PathArray &aPath, int aPermissionLevel ) :
   path(aPath),
   permissionLevel(aPermissionLevel)
 {
 }

Of course, holding references like this is a little scary so you might want to consider using a boost::shared_ptr or something similar instead to make the lifetime management more robust.

Upvotes: 3

cooky451
cooky451

Reputation: 3510

  1. You cannot assign arrays as you do with value types in C++
  2. int path[x][y] resolves to the type int (*)[y]

Possible solutions are:

  1. Using memcpy/copy
  2. Using std::array

Upvotes: 2

BigBoss
BigBoss

Reputation: 6914

In C++ '=' implemented for primitive types like int and double but not for array(array is not a primitive type), so you should never use '=' to assign an array to new array, instead you should use something as memcpy to copy array. memcpy copy a memory over another memory, so you can use it to copy an array over another array:

// memcpy( dst, src, size );
memcpy( this->path, path, FieldSize::HEIGHT * FieldSize * WEIGHT * sizeof(int) );

Upvotes: -3

Some programmer dude
Some programmer dude

Reputation: 409442

You can't assign to an array like that. However you can use the fact that an array is a contiguous memory area, even when having an array of arrays, and use e.g. memcpy to copy the array:

memcpy(this->path, path, FieldSize::HEIGHT * FieldSize::WIDTH * sizeof(int));

Upvotes: 0

Related Questions