Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with pointer to character array C++

Tags:

c++

I have what I thought should be a very simple snippet of code to write, though I'm unable to compile for a reason which I do not understand.

The following simplified code will not compile:

char buffer[9] = "12345678";
char* pBuffer = &buffer;

Compiler (g++) throws the following error:

error: cannot convert 'char (*)[9]' to 'char*' in initialization

C++ isn't exactly my "native" language, but everywhere I've looked tells me this should work. Any ideas or advice is greatly appreciated.

like image 405
Daniel S Avatar asked Jan 07 '13 04:01

Daniel S


3 Answers

Instead of taking the address of the array, write

char buffer[9] = "12345678";
char *pBuffer = buffer;

Edit: What does it all mean?

  • An array of type T of length n is a (contiguous) sequence of n T's in memory.

  • A pointer is a memory address.

So for example, the following code

char a[5] = "hello";
char *p = "world";

corresponds to the following situation in memory:

Comparing an array to a pointer.

In your code, you have created an array

char buffer[9] = "12345678";

in just the same way as the array char a[5] = "hello" was created. You intend to create a pointer char * which points to the first character of the array, just as char *p above points to the first character of the array "world".

When an expression of type "array of type" (here buffer) is used, it always "decays" to a pointer to the first element unless

1. the expression is used as the operand of sizeof (in sizeof(buffer), buffer does not decay to a pointer)

2. the expression is used as the operand of unary & (in &buffer, buffer does not decay to a pointer)

or

3. the expression is a string literal initializer for a character array (in char someBuffer[3] = "ab", the string literal "ab", an array, does not decay to a pointer).

This is laid out in section 6.2.2.1 of the standard:

729 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue.

As a result, all that you need to do to create a pointer char *pBuffer to the first character in your array is write

char *pBuffer = buffer;
like image 67
Nate Chandler Avatar answered Nov 11 '22 06:11

Nate Chandler


  • The declaration char buffer[9] = "12345678"; creates an array of 9 chars.
    Here, buffer is the address of its first element but not of the array.

  • char* pBuffer = buffer; is a correct expression as pBuffer is a pointer to char and can address the first element.

  • But the expression char* pBuffer = &buffer is wrong, because pBuffer can't address an array. (error in your code, &buffer address of array as explained below)

Difference between buffer and &buffer

&buffer means address of array. The values of buffer and &buffer are really the same, but semantically both are different. One is an address of a char, while the other is an address of an array of 9 chars.

buffer[9] = "12345678";


+----+----+----+---+---+----+----+----+---+----+ 
| '1'| '2' |'3'|'4'|'5'| '6'| '7'|'8' | 0 |  ...........
+----+----+----+---+---+----+----+----+---+---+----+  
 201   202  203 204 205 206  207   208 209 210  211
  ^     ^                                         
  |     |                                         
(buffer) (buffer + 1)                                         
|                                         |
|-----------------------------------------|--------
|201                                      | 210
  ^                                          ^
  |                                          |
(&buffer)                                 (&buffer + 1)     

I used decimal numbers for address instead of hexadecimal

Even though the value of buffer is 201 and the value of &buffer is 201, their meaning is different:

  • buffer: first element's address—its type is char*.
  • &buffer: complete char array's address—its type is char(*)[9].

Additionally, to observe the difference, add 1 :

buffer + 1 gives 202 that is the address of the second array element '2' but
&buffer + 1 gives 210 which is the address of the next array.

On My System, I write following code:

int main(){
   char buffer[9] = "12345678";
   char (*pBuffer)[9] =  &buffer; 

   printf("\n %p, %p\n",buffer, buffer+1);
   printf("\n %p, %p\n",(&buffer), (&buffer+1));
}  

And the output is as below:

0xbfdc0343, 0xbfdc0344

0xbfdc0343, 0xbfdc034c

[ANSWER]

That's the reason Error is:

error: cannot convert 'char ()[9]' to 'char' in initialization

You are trying to assign 'char (*)[9]' type value to char*.

  • char (*ptr2)[9]; Here ptr2 is pointer to an array of 9 chars, And this time
    ptr2=&buffer is a valid expression.

How to correct your code?

As in Nate Chandler's answer:

char buffer[9] = "12345678";
char* pBuffer =   buffer;   

or another approach,

char buffer[9] = "12345678";
char (*pBuffer)[9] =  &buffer;       

Which you choose depends on what you need.

like image 31
13 revs, 2 users 88% Avatar answered Nov 11 '22 05:11

13 revs, 2 users 88%


array decays to pointer, you only need

char* pBuffer = buffer;

Also checkout: std::decay

   std::cout << "int[] -> int*; // " << std::boolalpha
              << std::is_same<int *, std::decay<int[]>::type>::value;

Output:

int[] -> int*; // true
like image 41
billz Avatar answered Nov 11 '22 04:11

billz