Pointer logic

Asked

Viewed 654 times

6

In C++, you can do the following:

int variavel[10][10];
int** variavel;

But when I want to create an array 2d, where I can have the first part "unlimited" and the second part with limit?

tipo ponteiro nova_variavel[limite]

And the "reverse"?

tipo nova_variavel[limite] ponteiro

For example:

int* a[5]; //Ponteiro de arrays

Or

std::vector<int*> a; //Array de ponteiros

char* A[6];
A[1] = "Hello,";
A[2] = " World";
std::array<char*,2> a;
a[1] = "Hello,";
a[2] = "World!"; // <- Repare 1 caractere a mais. É pouco, mas pode fazer diferença.
  • 1

    The question is already answered, but if I may add that although it is easier to use, multi-dimensional arrays are much less efficient than one-dimensional arrays, either by the number of allocations, is because the memory stays in different places and harms the cache. You will always be able to use an array[100] instead of an array[10][10].

  • @C.E.Gesser actually, it’s best to use an STL container :). But IF I needed to, I would use two-dimensional arrays to make it more organized (depending on the case, of course!).

  • 1

    @C.E.Gesser the allocation of a multidimensional is also linear in memory. And say array[a][b] is as efficient as it would be array[a*10+b]. There’s not that much difference.

  • @Lucashenrique A container will cause dynamic and potentially non-linear allocation (except std::array). So they are not ideal in all cases. But yes, they are the easiest and least likely alternative to errors.

  • For an array is true, I was referring more to cases where something like int **array = new int*[N]; for(int i=0; i<N; ++i) array[i] = new int[M];, I should have been more explicit. About the containers, std::vector always has a contiguous allocation. It is almost never wrong to choose it.

  • @C.E.Gesser STL Forever!

Show 1 more comment

2 answers

4


Arrays and pointers are quite different concepts. A pointer has nothing to do with an "unlimited array". Come on:

int lista[10][10];

Here you are declaring a two-dimensional array with 100 elements. The name of that array is lista. When you write lista[4][2] you access an element and this results in a int. However if you write only lista in its expression, that is, when you try to access the array by name, it decay on a pointer to the first element. The detail here is that it is not possible to represent the array type directly, it will decay into a pointer whenever requested. You can do the following then:

int lista[10][10];
int* ponteiro1 = lista; // ponteiro1 é &lista[0][0]
int* ponteiro2 = lista[3]; // ponteiro2 é &lista[3][0]

When you do the following

int** ponteiro;

It’s just creating a pointer that points to a pointer that points to a int. There are no arrays here. The notation ponteiro[2][3] that it is possible to represent a bit of algebra with pointers, being equivalent to *(*(ponteiro+2)+3). This may not even result in a valid memory location.

Yet another possibility:

int* lista2[10]; // array de ponteiros

Here you have a simple one-dimensional list, whose element is a pointer int*.

The last notation of your question (tipo nova_variavel[limite] ponteiro) would aim to create a name pointer nova_variavel pointing to an array of limite elements of the type tipo? In this case your definition is written like this:

int (*variavel)[10]; // ponteiro de arrays

Not so intuitive, perhaps. An example:

int main() {
    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int (*ponteiro_para_array)[10] = &array;
    cout << (*ponteiro_para_array)[5] << endl; // mostra 6
}

One way to escape these complications when declaring a variable with an unusual type is to name each part of its type. For example (C++11):

using int10 = int[10]; // Cria um alias para a array de 10 ints
int10* variavel; // Exatamente o mesmo que a declaração anterior
  • Heheh, @Guilhermebernal I’ve been working with the language for 5 years, I know the differences of array and all, but what’s the difference of char array[] = "TEST"; and char* array = "TEST"; aesthetically? I know, Dereferencing...

  • @Lucashenrique char array[] = "TEST"; creates its own copy of the string while the char* array = "TEST"; points to a "shared" and read-only copy. They are quite different, semantically.

  • why no one would use the de-reference operator in such cases.

  • @Lucashenrique Why not? I can use *array to read 'T' in both cases.

  • Oops. I got confused - reference: Only if you take the address in memory

  • @Lucashenrique in the case of the array, the most you can do is take a reference to the first element, not the array itself. But in the case of the pointer, it can be useful in some function that wants to modify the argument by moving the pointer or something like that. I fail now to find an example.

Show 1 more comment

0

I believe having an "array of pointers" makes sense, but an "array pointer" doesn’t. If you declare:

int *variavel[10];

What you’re saying is, "allot memory in the stack to 10 pointers for integer, and give me the address of the first of them". In this case, the second part is "unlimited" in a way - since you can make each of these pointers reference an array of any size (provided you memory for each of them too, of course).

On the other hand (which I won’t give an example, as far as I know doesn’t exist) it would be like saying: "create a pointer that only referenced integer arrays size 10". I mean, you’re imposing a additional restriction (Constraint) on objects that that pointer can reference, and that’s not something supported by the C++ language (or any language I know). Because the only constraint you can place on a pointer is the specification of its type - and nothing pertaining to its contents.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.