0

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... 
Clifford
  • 88,407
  • 13
  • 85
  • 165
jdl
  • 6,151
  • 19
  • 83
  • 132
  • a will lower it as it is user defined type. – jdl Jan 04 '18 at 21:20
  • reopened - this is a C question, other suggestion was C++ , and the questions were different anyway (on this one OP just wants `char (*p)[2]` whereas on the other question OP wanted pointer to pointer) – M.M Jan 04 '18 at 21:48
  • @M.M. Quite so, although given the error messages the OP has reported on suggested solutions, I suspect he is using C++ compilation. I disagree the question is not otherwise the same however. The question explicitly shows an attempt to access `pointer[0][1]` for which a pointer-to-pointer will not work The code fragment here is more or less identical. The accepted answer however is incorrect - the answer that follows it with more votes is correct. https://stackoverflow.com/questions/10165627/how-to-assign-two-dimensional-array-to-pointer – Clifford Jan 04 '18 at 22:10
  • @Clifford in C the answer is good practice though, not **infinitely nasty** as suggested by that answer. (Actually I wouldn't call it infinitely nasty in C++ either). And the OP on that thread said that that answer didn't solve their problem. – M.M Jan 04 '18 at 22:12
  • @M.M. It did not solve the problem because he misunderstood the answer. It was a pointer to _any number_ of 1 dimensional arrays, and each one may be indexed. What the answer lacked was a demonstration of accessing the array content through the pointer using two dimensions. – Clifford Jan 04 '18 at 22:30

4 Answers4

1

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.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • If I change it to definition of char pc[6] = { 1,2,3,4,5,6 }; I get the error: 'initializing': cannot convert from 'char(*)[6]' to 'char*' – jdl Jan 04 '18 at 21:27
  • @jdl try it now – klutt Jan 04 '18 at 21:29
  • Severity Code Description Project File Line Suppression State Error C2440 'initializing': cannot convert from 'char ( * )[3][2]' to 'char ( * )[2]' – jdl Jan 04 '18 at 22:01
  • @jdl What compiler are you using? Works flawlessly for me and not warnings with -Wall -Wextra – klutt Jan 04 '18 at 22:02
  • compiler VS2017 – jdl Jan 04 '18 at 22:05
  • The guy below... works... however... The question still remains... can I set a pointer to this without any dimension... and work the dimensions later on a memcpy? – jdl Jan 04 '18 at 22:10
  • @M.M Thanks. To much copy pasting back an forth. – klutt Jan 04 '18 at 22:11
0

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;
LosWochos
  • 322
  • 1
  • 9
  • on building from your response: I get the error: 'initializing': cannot convert from 'char(*)[3][2]' to 'char*' – jdl Jan 04 '18 at 21:23
  • Sorry. I made a mistake. As pc is an array you need a slightly different syntax. – LosWochos Jan 05 '18 at 07:37
0

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  
jdl
  • 6,151
  • 19
  • 83
  • 132
-2

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.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • using your code I get the error: 'initializing': cannot convert from 'char**' to 'char(*)[2]' – jdl Jan 04 '18 at 21:49
  • 1
    This answer makes no sense – M.M Jan 04 '18 at 21:50
  • @M.M In what way? – Clifford Jan 04 '18 at 21:50
  • 1
    In any way whatsoever – M.M Jan 04 '18 at 21:52
  • @jdl : It will produce the error message you describe if you use C++ compilation, but you have tagged the question C. – Clifford Jan 04 '18 at 21:54
  • @M.M : Not helpful - I cannot fix it if you are not explicit: It can be executed at https://onlinegdb.com/r1abQXnmz. It is possible the answer is unclear, or simply that you do not understand it - that is not the same as "no sense". – Clifford Jan 04 '18 at 21:56
  • Why do you want to cast `pc` to `char **`? – klutt Jan 04 '18 at 21:58
  • @klutt : I don't - my error - copied from original code. It now works in C and C++. Thanks. – Clifford Jan 04 '18 at 22:02
  • 1
    The page you link to is suppressing error messages, the code contains a constraint violation (`char **` may not be implicitly converted to `char (*)[2]`) . `char **` in OP's code didn't work because `char **` means "pointer to `char*`" and there was never any `char *` object in the first place to point to. It is nothing to do with "size and dimension information" as you suggest – M.M Jan 04 '18 at 22:07
  • The question still remains... can I set a pointer to this without any dimension... and work the dimensions later on a memcpy? – jdl Jan 04 '18 at 22:08
  • 1
    `char* p = &pc[0][0];` would give you a pointer to a block of memory with no dimension information. – Igor Tandetnik Jan 04 '18 at 22:12
  • 2
    @jdl you never mentioned anything about "working dimensions later on a memcpy" in your original question. If you still have a problem then post a new question that asks about your actual problem. (Don't edit this question to ask a new question) – M.M Jan 04 '18 at 22:13
  • @jdl : With respect that question does not "remain"; you did not ask that question. – Clifford Jan 04 '18 at 22:14
  • @M.M : That is a long way from making "no sense". The link refers to my original code, not the corrected code. The error you mentioned is generated when C++ compilation is used. https://onlinegdb.com/rJI8dX2XM, but as you pointed out - this is a C question. However the updated code compiles as C or C++. – Clifford Jan 04 '18 at 22:21
  • 1
    @Clifford `char (*p)[2] = (char **)pc;` is an error in both C and C++. (I can quote the relevant standard paragraphs if you like).. The updated code in this answer is correct, and the update to the second paragraph is good, although the first paragraph is still bogus – M.M Jan 04 '18 at 22:24
  • To wade in here before turning in for the night: @M.M is correct thus far on all points. – Bathsheba Jan 04 '18 at 22:30
  • @M.M. There is a general point that pointers have no information regarding the number of objects they point to which is what I was trying to express perhaps somewhat inelegantly. I have re-expressed that. Your assistance in improving the answer is appreciated. Regarding the `(char**)` cast and OnlineGDB - it issues the error for C14 compilation, but I selected C (which appears to be ISO C99), the question is tagged [visual-c++] whose C compilation is only ISO C90. It was nonetheless a copy&paste error from the OP's original code and not intentional. – Clifford Jan 04 '18 at 23:01
  • As mentioned earlier, the site you're using is suppressing error messages. The edit to your first para doesn't help - it's describing why `char *` would not work for the purpose; the reason why `char **` does not work is still that there are no `char *` objects to point to. – M.M Jan 04 '18 at 23:06
  • @M.M. It is using GCC 5.4.1 C99. It unfortunately does not display the compiler settings or allow fine control of them. I assume they are defaults, e.g.. no `--pedantic -Werror` it is presumably as permissive as C99 allows. – Clifford Jan 04 '18 at 23:19
  • @M.M : I have modified it further. You are free to edit it. The time you have spent on it however you might have posted an answer yourself. – Clifford Jan 04 '18 at 23:32