Reputation: 79113
What is the difference between these two initializations?
char a[] = "string literal";
char *p = "string literal";
Upvotes: 2
Views: 1289
Reputation: 74450
Although the two look similar and are often used interchangeably, they do mean different things. The first line:
char a[] = "string literal";
... creates an array that is large enough to hold the string literal, including its NUL terminator. It initializes this array with the string literal you specified. One benefit of this version is that the array can be modified at a later time. Also, the array's size is known even at compile time, so you can use the sizeof
operator to determine its size. For example:
printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size
// including the NUL terminator
The second line:
char *p = "string literal";
... just sets a pointer to point to a string literal. This is faster than the first version, but you have the drawback that the literal should not be changed, because it may reside in a page marked as read only. You also have the drawback that to know the length of the string, you will need to use the strlen()
function, since the sizeof
operator will just give you the size of the pointer variable. For example:
printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on
// whether this is a 32-bit or 64-bit build
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not
// including the NUL terminator
As to which is better, it depends on what you will be doing with these variables. If you do not need to make any changes to the string, use the later, but do change the char *
to a const char *
, so that you don't accidently attempt making changes to the characters being pointed to. If you do intend to change the data, use the former array based version which allows you to make changes to the array after initialization.
Upvotes: 17
Reputation: 400079
One gives you an array filled with the data you specify, the second gives you a pointer to some memory (typically read-only) somewhere, containing the data you specified.
To make the difference in "what you get" more clear, try this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char a[] = "string literal";
char *b = "string literal";
printf("a is %lu bytes, b is %lu\n", (unsigned long) sizeof a,
(unsigned long) sizeof b);
return EXIT_SUCCESS;
}
Here is a live demo with the above code.
Upvotes: 0
Reputation: 490623
Each forces the compiler to create a string literal in static memory that's (at least conceptually) read-only.
The first then uses that to initialize the contents of an array. The string literal is just used to pick its size, and to initialize it.
The second creates a pointer directly to the original string literal itself.
There is no real better or worse between them. They're just different. For example, the array usually uses more memory (there's a string literal, then there's a complete copy of the string literal in your array). Since it's an otherwise normal array, however, you can modify it if necessary.
The pointer directly to the string literal will often save some memory. It also means you can assign a different value to the pointer so that it (for example) points at different string literals at different times. You are not, however, allowed to modify the data it points at -- doing so will give undefined behavior.
Upvotes: 3
Reputation: 1
The first declares an array and fill it (by setting the elements one by one, till the ending null byte included). The array can be modified.
The second declares a pointer, and fill it by setting it to a constant literal. You can modify the pointer (e.g. to make it point elsewhere), but you cannot modify the constant string (which on most systems will be put in a read only segment) pointed by it.
Upvotes: 0
Reputation: 124770
Depends on what you need.
char a[] = "string literal";
Creates a mutable character array with automatic storage duration. This is legal:
a[0] = 'c';
On the other hand...
char *p = "string literal";
Creates a pointer to readonly memory. The declaration should really be
const char *p = "string literal";
You cannot legally modify what p
points to.
Upvotes: 0