user3835277
user3835277

Reputation:

What is the difference between std::string (*)[96][60] and std::string* [96][60]?

I have multiple two-dimensional 96-by-60 std::string arrays. I'm trying to make a pointer that can point to one of these arrays.

The arrays look something like this:

std::string array1[96][60];
std::string array2[96][60];

The pointer I made looks like this:

std::string *ptr_to_array[96][60];

Everything compiles if I just declare the pointer. But when I try to do the following

ptr_to_array = &array1;

I get this error:

error: incompatible types in assignment of ‘std::string (*)[96][60]’ to ‘std::string* [96][60]’

To me, it appears both types are the same.

Also, from what I've read on this subject, lots of people recommend using std::array. I would, but it seems like an even bigger problem than this when trying to deal with multidimensional std::arrays. I'd prefer to just fix my std::string arrays, but would it be better or easier to just switch to std::array?

Upvotes: 2

Views: 85

Answers (4)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145279

I'm guessing that you want a pointer that you can index in the same way as the original array:

#include <string>
#include <iostream>
using namespace std;

auto main() -> int
{
    string array1[96][60] = {{"Alpha", "Bravo", "Charlie"}};
    string array2[96][60];

    string (*p)[60] = array1;

    cout << array1[0][2] << endl;
    cout << p[0][2] << endl;
}

Instead of battling the C syntax directly like above, you can use typedef or C++11 using to define names for types, which makes things more clear:

#include <string>
#include <iostream>
using namespace std;

auto main() -> int
{
    using String_row    = string[60];
    using String_matrix = String_row[96];

    String_matrix array1 = {{"Alpha", "Bravo", "Charlie"}};
    String_matrix array2;

    String_row* p = array1;

    String_matrix* pa = &array1;

    cout << array1[0][2] << endl;
    cout << p[0][2] << endl;
    cout << (*pa)[0][2] << endl;
}

If you really want a pointer to the array itself, not a nicely indexable pointer to the first item of the array, then at the C syntax level it would go like

string (*pa)[96][60] = &array1;

and you'd use it like

cout << (*pa)[0][2] << endl;

It's the same memory address as the pointer-to-first-item, but of slightly different type.


All that said, I recommend defining or using a matrix class based on std::vector as storage provider, instead of directly using raw arrays.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

The types are not the same. std::string* [96][60] is a 2D array of pointers. std::string (*)[96][60] is a pointer to a 2D array.

  • Taking description literally, you need something along the lines of

    std::string (*ptr_to_array)[96][60];
    ptr_to_array = &array1;
    

    Later you can access the array through the pointer as

    (*ptr_to_array)[i][j];
    

    In this case you literally declare ptr_to_array as a pointer to a 2D array.

  • Alternatively, you can do

    std::string (*ptr_to_array)[60];
    ptr_to_array = array1;
    

    and later access it as

    ptr_to_array[i][j];
    

The former variant will enforce full match of both array sizes when intializing the pointer. The latter variant ignores the first array size.

  • You can also use a reference to an array in the first variant

    std::string (&ref_to_array)[96][60] = array1;
    

    which will preserve the "natural" array access syntax

    ref_to_array[i][j];
    

    But references have to be initialized at the point of declaration.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311018

This

std::string *ptr_to_array[96][60];

is not a declaration of a pointer. It is a declaration of a 2D array of pointers to objects of type std::string.

If you want to use expression

&array1

and assign it to a pointer then the pointer has to be defined like

std::string ( *ptr_to_array )[96][60];
ptr_to_array  = &array1;

But I suspect that actually you need a pointer to the first element of the array. In this case the declaration will look like

std::string ( *ptr_to_array )[60];
ptr_to_array  = array1;

Upvotes: 0

user2946316
user2946316

Reputation:

If i understood you question right, this is what you are looking for right?

std::string array1[3][3];
std::string array2[3][3];
auto* test = &array1;

std::cout << test[0] << std::endl;

test = &array2;

std::cout << test[0] << std::endl;

Upvotes: 0

Related Questions