I'm unsure of how declaring **x (a pointer to a pointer of x) is the same as declaring x[][] (a two-dimensional array of x's)... The theory I have is this:

int *x = {whatever}; (x is a pointer to the first int value)
*x (first array item, value pointed to by x)
x[2] (goes to the location pointed to by x, plus sizeof(int)*2, resulting in third item in the array)

yes?

--edit--

if my understanding is correct, is this what is referred to as "pointer arithmetic?"

Dani AI

Generated

Short answer: arrays and pointers are closely related, but they are different types with different semantics. Saying "yes" (as did) captures the intuition that indexing uses pointer arithmetic, but it misses important type- and layout-level differences that and began to point out.

A concrete illustration: a true 2D array is an array of fixed-size rows; a pointer-to-array remembers the row size. Contrast that with a pointer-to-pointer, which is just a pointer to pointers (no guaranteed contiguity).

int mat[2][3] = {{1,2,3},{4,5,6}};
int (*rowPtr)[3] = mat;   // rowPtr points to arrays of 3 ints

int v1 = mat[1][2];       // OK, value 6
int v2 = rowPtr[1][2];    // OK, value 6

// This is NOT a correct substitute:
// int **pp = mat;        // type mismatch; will not compile

Key practical differences to keep in mind:

  • Pointer arithmetic steps by the pointed-to type size. rowPtr+1 advances by sizeof(int[3]) (three ints). An int** increments by sizeof(int*). Mixing them leads to wrong addresses.
  • A real 2D array is contiguous in memory; int** usually points to separately allocated rows — p[i][j] will work only if each p[i] is a valid pointer to a row.
  • sizeof distinguishes them: sizeof(mat) gives total bytes of the array; sizeof(somePtr) gives pointer size.
  • Array-to-pointer decay happens in most expressions, but not for sizeof, unary &, or when binding to an array reference.

Troubleshooting tips: if indexing a dynamically-built "2D" structure segfaults, check whether rows were allocated and assigned to the pointer-to-pointer. For contiguous storage prefer a single allocation (or std::vector) and index with i*cols + j, or use int (*p)[cols] when cols is compile-time known. Use const char* for string literals to avoid undefined behavior when trying to modify them.

Recommended Answers

All 4 Replies

"Yes."

"Yes."

Ditto. Yes with quotes around the word "yes". The phrasing of this sentence is a bit loose and inaccurate.

I'm unsure of how declaring **x (a pointer to a pointer of x) is the same as declaring x[][] (a two-dimensional array of x's)... The theory I have is this:

**x is a pointer to a pointer to an integer not "a pointer to a pointer of x", and you can have a two-dimensional array of integers, but you can't have a two-dimensional array of x's


x[][] and **x are definitely not the same, but when used to dereference addresses, can accomplish the same thing.

#include<iostream>
using namespace std;


int main ()
{
    int y[4];
    y[0] = 5;
    y[1] = 10;
    y[2] = 15;
    y[3] = 20;
    
    int *x = y;
    int *z = x + 2;
    cout << *z << endl;
    cin.get ();
    return 0;
}

Here's an example, though it is a one-dimensional example, not a two-dimensional example. The line in red is an example of pointer arithmetic. The program will output 15.

okay I see,
and yeah I guess the phrasing was a bit loose... but with a char array,
you can define it char x[]="rawrawrawrawrawr"; or char *x="rawrawrawrawrawr"; and have it behave the same, no? Isn't there really no difference between pointers and arrays (since there isn't any bounds checking of arrays...you could just go p[5] even if p is just used as a pointer to some object, couldn't you?) it seems like the [0] is exactly the same as *, except the []s just tell the compiler to add an amount to the address of the pointed-to address in the machine instruction (mov eax,[ebp+whatever])... so what's the difference between **x and x[][]?

--edit--

aside from the fact that int x[5] would allocate the appropriate amount of space to the stack (or heap), where as declaring it int *x cannot have this functionality.

you can't do one of the following even , if you thinks that way.
That's the difference

char ** chararrayarray =
{
	"My first string " ,
	"My Second string " ,
	"My third string",
	"My fourth string "
};

the meaning of this is pointer to pointer to a char , but it can continue until it found the zero character. so this is wrong then.
or

char [][] chararrayarray =
{
	"My first string " ,
	"My Second string " ,
	"My third string",
	"My fourth string "
};

the meaning of this is array of ( char array)

but

char *chararrayarray[] =
{
	"My first string " ,
	"My Second string " ,
	"My third string",
	"My fourth string "
};

is correct ! That's the difference. The meaning of this is array of (char *) , so you can openly do this.

but you can do this.

char * chararrayarray1[] =
{
	"My first string " ,
	"My Second string " ,
	"My third string",
	"My fourth string "
};

char **  chararrayarray =chararrayarray1 ;

and try this program .

#include <iostream>
using namespace std ;

char * chararrayarray1[] =
{
	"My first string " ,
	"My Second string " ,
	"My third string",
	"My fourth string "
};

char ** chararrayarray = chararrayarray1 ;


int main(int argc, char* argv[])
{
	cout << *(chararrayarray) <<endl ;
	cout << *(chararrayarray+1) << endl ;
	cout << *(chararrayarray+2) << endl;
	return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.