Samuel Liew
Samuel Liew

Reputation: 79113

C "string" init - which is better?

What is the difference between these two initializations?

char a[] = "string literal";

char *p  = "string literal";

Upvotes: 2

Views: 1289

Answers (5)

Michael Goldshteyn
Michael Goldshteyn

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

unwind
unwind

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

Jerry Coffin
Jerry Coffin

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

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

Ed Swangren
Ed Swangren

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

Related Questions