10

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.

4
  • 5
    Here's a hint: Arrays decay to pointers. Commented Jan 7, 2013 at 4:42
  • 2
    Such a classical pointer example. Wouldn't it be char *pBuffer = buffer; ? Commented Jan 7, 2013 at 4:45
  • @DanielS check my answer , May be helpful to you to know how error occur in your code. Commented Jan 7, 2013 at 10:04
  • 1
    See also: How come an array's address is equal to its value in C? Commented Jan 7, 2013 at 14:24

6 Answers 6

20

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;
Sign up to request clarification or add additional context in comments.

4 Comments

Nate,This worked - thank you very much. Although, I'm still wondering... why? What exactly is the difference in syntax causing? Edit: still getting used to this board, removed my additional question.
@DanielS for a tl;dr: an array decays to a pointer to the first element. Taking the address of an array makes a pointer to an array (which is a distinct type), not a pointer to the first element of that array. So arrays convert directly to pointers.
Pointer are used to hold memory addresses. An array variable name is a pointer to first byte of consecutive memory location. in your case buffer is a special pointer that hold address for first byte of character array. So, you can assign it directly as in accepted answer.
@NateChandle Now it become nice answer! Good explained
12
  • 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.

Comments

4

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

Comments

2

The error message is very clear; &buffer is of the type char (*)[9], i.e., a pointer to an array of char with 9 elements (yes, arrays are fully fledged types).

That is not the same as a char*. However, arrays degrade to pointers to the first element when needed, so...

char *pbuffer = buffer;

1 Comment

Anyone want to explain the -1?
0

Name of array indicates it's base address, so if you just write buffer, it means address of buffer[0]. If you are using &buffer, you need to take it in char** not in char *.

So,

char* pBuffer = buffer;

Would be correct as suggested.

Comments

-1

because the compiler can't implicitly convert char()[] to char. So you need explicit type conversion

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

4 Comments

Sure it works in this case, but I find the fact that you're promoting that you should just shut the compiler up instead of actually fixing the error a bit irritating.
Yes, it is. But in this problem, I think the asker want to know why the compiler said "cannot convert". So I suggust the type conversion
-1 Why in the world would you suggest taking the address of an array and casting it to a pointer to the first element when you could simply make the assignment correctly? I can cast something to whatever I want to, that doesn't make it correct or optimal.
@slggamer: Sure compiler will not give error for this, because C-Style casting this types of conversion, but this is not what we need to do. It will not serve the purpose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.