Setting a Pointer to a block of stack memory?

705 Views Asked by At

I want to create a pointer to a block of stack memory. I don't want to copy the contents, just have a pointer to it. How should I do that?

This is what I tried...

char p[3][2] = { 1,2,3,4,5,6 };
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]); //works fine 

char pc[3][2] = { 1,2,3,4,5,6 };
char **p = (char**)pc;//No error here... but shows on next line when accessing through the pointer
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);  //ERROR:  an Exception thrown here... 
4

There are 4 best solutions below

20
On BEST ANSWER

Pointers are not arrays, and a char** does not retain the information necessary to index a second dimension of any array it might point to.

So rather than char** you need a pointer to a char[2] array, because otherwise the size of the second dimension of pc is not known to p, such that p[n] cannot be determined.

You can solve that by declaring a pointer-to-an-array as follows:

char pc[3][2] = { 1,2,3,4,5,6 }; 
char (*p)[2] = pc;
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], 
                                     p[1][0], 
                                     p[2][0], 
                                     p[0][1], 
                                     p[1][1], 
                                     p[2][1] ) ;

For it to produce correct results, the dimension of the p pointer must exactly match the second dimension of the two dimensional array pc array.

2
On

A pointer is a variable that stores the memory address of something. Hence, you need to assign the memory address of pc to a pointer to pc. You get the memory address of something via the address operator &.

The pointer to pc is

CHAR *ppc = &pc[0];

or simply:

CHAR *ppc = pc;
7
On

You have to differ between pointers and arrays.

char **p meant that p is a pointer to pointer to char. Use char *p instead.

char *p = &pc;

This does not make you able to use p[x][y] notation. To do that, we can do like this:

char (*p)[2] = pc;

It works when I tried your code. Here it the complete main:

int main()
{
    char pc[3][2] = { 1,2,3,4,5,6 };
    char (*p)[2] = pc;
    printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);
}

It compiles without warnings (well, I did not introduce any warning that was not there before) and outputs this:

$ ./a.out 

LIST:1,3,5,2,4,6

To remove the warning, change

char pc[3][2] = { 1,2,3,4,5,6 };

to

char pc[3][2] = { {1,2},{3,4},{5,6} };

Thanks to M.M for improvements.

0
On

This is what I did:(I don't want to specify the size of the pointer in defining it. In redefining I will specify the size)

//assigning a pointer to a matrix
char pc[3][2] = { 1,2,3,4,5,6 };
char *pp;//this pointer(as a member) will be carried between classes.      
pp = &pc[0][0];//set pointer to the address of the first element:  via:  Igor Tandetnik

//redefining, validation and display
char p[2][3]; 
memcpy(p, pp, sizeof(char) * 6);
printf("\nLIST:%d,%d,%d,%d,%d,%d\n", p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1]);

What is interesting is that for a 1d array you set the pointer to the array name(address of) and not the address at the first element.

char pc[6] = { 1,2,3,4,5,6 };
char *pp;
pp = pc;//set pointer to the address of the 'pc', not the first element