What is the difference between char * and int * types to create an array of pointers in C ++?

When creating an array of pointers for the int data type, the following code works:

 int var[] = {10, 100, 200, 1000}; int *ptr[] = {&var[0], &var[1], &var[2], &var[3]}; 

When creating an array of pointers for a char data type, the following is valid:

 char *names[] = {"Mathew Emerson", "Bob Jackson"}; 

But if I create an array of pointers for the int data type as follows:

 int var[] = {10, 100, 200, 1000}; int *ptr[] = {var[0], var[1], var[2], var[3]}; 

I get a compiler error. I understand why I get a compilation error in the above declaration method for an array of int data type, since var [i] is not a reference to the variable that the pointer should point to, that is, its address, but shouldn’t also get an error by the same logic in the declaration of my char pointer.

What is the reason for its acceptability in an array of char pointers?

Is the "string value" the address of what the pointer points to, or is it just the string value of the constant.

+5
source share
4 answers
 char *names[] = {"Mathew Emerson", "Bob Jackson"}; 

Not legal in C ++. The string literal is of type const char[] , so it cannot be stored as char* , because it violates const-correctness. Some compilers allow this to be compiled as a legacy from C, since string literals are of type char[] , but this is not standard C ++. If you include warnings in your compiler, you should get something in the lines

 main.cpp: In function 'int main()': main.cpp:5:53: warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic] char *names[] = {"Mathew Emerson", "Bob Jackson"}; 

If you need an array of strings, I suggest you use std::string as

 std::string names[] = {"Mathew Emerson", "Bob Jackson"}; 

Cause

 char *names[] = {"Mathew Emerson", "Bob Jackson"}; 

"works" is that since string literals are arrays, they implicitly decay into pointers, so

 {"Mathew Emerson", "Bob Jackson"} 

becomes

 { address_of_first_string_literal, address_of_second_string_literal} 

and then they are used to initialize the pointers in the array.

 int *ptr[] = {var[0], var[1], var[2], var[3]}; 

It is impossible to work because var[N] is a reference to an int in an array, not a pointer.

+7
source

"Matthew Emerson" is of type const char* - it is already a pointer, so you can directly store it in an array of pointers. The reason you need & for the int case is to "convert" int to int* .

+1
source

(Ignoring the match problem, as mentioned in other answers ...)

Each string literal that you write ( "Mathew Emerson" , "Bob Jackson" , ...) requires some storage space in the compiled code later.

As if you were writing somewhere

 char const[] MathewEmerson = { 'M', 'a', /*...*/, 'o', 'n', 0 }; 

So you can build your char const * array, and then:

 char const* names[] = { &MathewEmerson[0], /*...*/ }; 

As with arrays, the address of the array itself and its first element are the same, and arrays are implicitly converted to pointers, instead you can write

 char const* names[] = { MathewEmerson, /*...*/ }; 

All this is done implicitly for you if you use string literals.

Similarly, you could write:

 int *ptr[] = {var, &var[1], &var[2], &var[3]}; 

(note: var , not &var[0] for the first element), and if we go further, even:

 int *ptr[] = {var, var + 1, var + 2, var + 3}; 

The result would always be the same. Readability, clarity of one option and another? Well, another topic ...

+1
source

Your delusion is completed in your interpretation of what is represented by: "Mathew Emerson"

This is an array of characters that will be created in read-only memory as part of your program bootstrap. This array of characters is called String Literal , namely:

Narrow multibyte string literal. Unsigned string literal type const char[]

NathanOliver's answer correctly describes that your compiler does not have a warning level raised high enough, so it allows const char[] decay to char* . This is very bad because:

Attempting to modify a string literal results in undefined behavior: they can be stored in read-only storage (eg .rodata) or in combination with other string literals [1]

It would be completely legal and logical to do this: const char *names[] = {"Mathew Emerson", "Bob Jackson"} I hope this clarifies to you that it is going well enough for you to understand that working with a string literal works with a pointer . Your code: int *ptr[] = {var[0], var[1], var[2], var[3]} is illegal because var[0] is int& not a int* . Similarly, it would be illegal: char* ptr = {names[0][0], names[0][1], names[0][2], names[0][3]} Again, the problem here was that I worked with char& not char* s.

+1
source

All Articles