Reputation: 81
I have an object which has a 2d char array as a property.
I'd like to create an accessor method which is able to return a pointer to this 2d array.
I have declaired the 2d array like this:
#define PRESET_LEN 15
#define NO_PRESETS 8
char camPresets[NO_PRESETS][PRESET_LEN];
Being new to C++ I'm having a bit of bother trying to fiigure out the method declairation.
So far I have this in the header :
char** getPresetsForCamera(int cam);
and this in the cpp
char** DataManager::getPresetsForCamera(int cam)
{
if(currentCam != cam)
load(cam);
return camPresets;
}
But it does not compile. I obviousely havn't understood how to use pointers properly, at least for 2d arrays, I thought I could just write 'return &camPresets;' to return the address of the array but I'm wrong. Please could someone show me where I'm going wrong. Thanks, Rick.
Upvotes: 2
Views: 892
Reputation: 81
Well, in the end after reading through the answers left here, I didn't want to import any libraries into my code so I stayed with a 2d array. I ended up using this code :
typedef char (*pointer_to_arrays)[PRESET_LEN];
pointer_to_arrays getPresetsForCamera(int cam);
then in the cpp
DataManager::pointer_to_arrays DataManager::getPresetsForCamera(int cam)
{
if(currentCam != cam)
load(cam);
return camPresets;
}
Thanks for the pointers :P
Upvotes: 0
Reputation: 218098
The correct ugly syntax is :
char (&DataManager::getPresetsForCamera())[NO_PRESETS][PRESET_LEN]
{
if (currentCam != cam)
load(cam);
return camPresets;
}
which may be simplified with a typedef
:
typedef char camPresetsType[NO_PRESETS][PRESET_LEN];
camPresetsType& getPresetsForCamera();
But I really suggest to use std::array
or custom class.
Upvotes: 2
Reputation: 36896
You have a number of options for returning a 2D array. One is to use a jagged array like are sort of trying to do. If you are truly using char **
as a 2D array, though, you should just stick with using it as a char **
jagged array, and not a 2D array as you are doing and why you see the compiler error.
Another option, if you insist on using true 2D arrays (they are, after all, more efficient than jagged arrays), is to just wrap the array in a struct and return the struct, like this:
struct camPresetsArray
{
char values[NO_PRESETS][PRESET_LEN];
};
camPresetsArray DataManager::getPresetsForCamera(int cam)
{
...
}
Another option is to pass the return value as a function argument.
typedef char camPresetsArray[NO_PRESETS][PRESET_LEN];
void DataManager::getPresetsForCamera(camPresetsArray& outp, int cam)
{
...
}
camPresetsArray x;
myDataManager.getPresetsForCamera(x, y);
Upvotes: 0
Reputation: 35454
If you are concerned with using std::vector
, then use std::array
.
#include <array>
#define PRESET_LEN 15
#define NO_PRESETS 8
typedef std::array<char, PRESET_LEN> InnerArray;
typedef std::array<InnerArray, NO_PRESETS> Array2D;
Array2D camPresets;
Array2D getPresetsForCamera(int cam)
{
return camPresets;
}
Upvotes: 0
Reputation: 4668
Well, you need to think that a pointer and array are semantically similar, but they have different syntax.
By defining a 2d array:
char arr[W][H];
you allow the compiler to calculate the location of the element in the original block of data. Remember that the element [0][0] is basically a pointer to the begining of assigned memory block. So for example, if you defined an array and accessed:
char arr[10][20];
char arr[5][5];
You'd tell the compiler to "move 5 rows, and 5 columns from the begining", which would be simply: 5*H+5 = 5*20+5 = 105.
Now, this bracket notation is additional information for the compiler. But as you know, the array is just a block of memory. You may consider to have the same meaning:
&arr[0][0] == arr; // true, arr is "char*"
What this means, is that the pointer notation no longer provides the compiler the widths of array dimensions, and so it cannot use the index operator. The array is considered a simple continuous block of data.
In your case you should simply return a char*. You cannot return an array from the function, but you may assign it to a pointer variable.
char* newArr = fun(); // char* fun() { char* test = new char[10*20]; return test; }
To avoid possible out of range errors, use std::vector instead.
Upvotes: 0
Reputation: 3407
You can dynamically allocate array for camPresets by declaring it as double pointer and return it in function
See an example
char **camPresets;
char** getPresetsForCamera(int cam);
char** getPresetsForCamera(int cam)
{
//your validation
return camPresets;
}
//Code to dynamically allocate memory
camPresets = (char**)malloc(NO_PRESETS* sizeof(char*));
// for each row allocate Cols ints
for (int row = 0; row < NO_PRESETS; row++) {
camPresets[row] = (char*)malloc(PRESET_LEN* sizeof(char));
}
Upvotes: 0
Reputation: 508
Here you go:
char* DataManager::getPresetsForCamera(int cam)
{
if(currentCam != cam)
load(cam);
return camPresets[cam];
}
Note that you should also check the bounds of that array before using it. Here's a safer version:
char* DataManager::getPresetsForCamera(unsigned int cam)
{
assert(cam < NO_PRESETS);
if(currentCam != cam)
load(cam);
return camPresets[cam];
}
Upvotes: 0