76

I know they are different, I know how they are different and I read all questions I could find regarding char* vs char[]

But all those answers never tell when they should be used.

So my question is:

When do you use

const char *text = "text";

and when do you use

const char text[] = "text";

Is there any guideline or rule?

As an example, which one is better:

void withPointer()
{
    const char *sz = "hello";
    std::cout << sz << std::endl;
}

void withArray()
{
    const char sz[] = "hello";
    std::cout << sz << std::endl;
}

(I know std::string is also an option but I specifically want to know about char pointer/array)

rve
  • 5,897
  • 3
  • 40
  • 64

7 Answers7

80

Both are distinctly different, For a start:

  1. The First creates a pointer.
  2. The second creates an array.

Read on for more detailed explanation:

The Array version:

char text[] = "text"; 

Creates an array that is large enough to hold the string literal "text", including its NULL terminator. The array text is initialized with the string literal "text".The array can be modified at a later time. Also, the array's size is known even at compile time, so sizeof operator can be used to determine its size.


The pointer version:

char *text  = "text"; 

Creates a pointer to point to a string literal "text". This is faster than the array version, but string pointed by the pointer should not be changed, because it is located in an read only implementation defined memory. Modifying such an string literal results in Undefined Behavior.

In fact C++03 deprecates use of string literal without the const keyword. So the declaration should be:

const char*text = "text";

Also,you need to use the strlen() function, and not sizeof to find size of the string since the sizeof operator will just give you the size of the pointer variable.


Which version is better?

Depends on the Usage.

  • If you do not need to make any changes to the string, use the pointer version.
  • If you intend to change the data, use the array version.

EDIT: It was just brought to my notice(in comments) that the OP seeks difference between:

const char text[] and const char* text

Well the above differing points still apply except the one regarding modifying the string literal. With the const qualifier the array test is now an array containing elements of the type const char which implies they cannot be modified.

Given that, I would choose the array version over the pointer version because the pointer can be(by mistake)easily reseated to another pointer and the string could be modified through that another pointer resulting in an UB.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 2
    I'd like to add that the pointer, unless it's a `char *const` or `char const *const`, can be reset to point to a different buffer, so in that restricted sense `text` can be changed. – Fred Foo Oct 26 '11 at 14:16
  • @Als: what about static const char[] as faenel noted in his/her answer? – rve Oct 26 '11 at 15:51
  • @rve: my nickname is spelled `Fanael`. That said, `faenel` appeals to a part of me :) –  Oct 26 '11 at 16:10
  • @rve: Modifying an variable which is `const` by typecasting or however results in an Undefined Behavior,I don't think it gets unnoticed often.BTW,To clarify you on your comment: `static const char[]` and `const char *` are **not same**,They still have the same exact differences which my above answer points out.Usage of `static` does not in anyways render the string literal modifiable. – Alok Save Oct 26 '11 at 16:21
  • @Als: I agree on the const part. But in your answer you mention `char*` is faster. Isn't `static const char[]` just as fast? It seems the `static const char[]` version has the advantages of both. You can use `sizeof`, it is faster and there is only one copy in memory? – rve Oct 26 '11 at 16:57
  • -1 He did not ask about `char text[]` vs. `char* text`, he asked about `const char text[]` vs `const char* text`. – BlueRaja - Danny Pflughoeft Oct 26 '11 at 17:11
  • @BlueRaja-DannyPflughoeft: Well point noted,it was I completely missed that,Anyways Modified the answer to account for that. – Alok Save Oct 26 '11 at 17:21
  • 1
    If you do not need to modify the data, using `const char text[]` reduces the number of relocations in the object file, and requires fewer machine code instructions to access. – Dietrich Epp Oct 26 '11 at 19:41
  • So, one could pass the pointer to another function and change the pointer in that other function by `*myvar = "new text";`? I tested that and it is possible. Now I wonder what happens with the initial memory using "text"? – David Villasmil May 18 '20 at 11:04
9

Probably the biggest difference is that you cannot use the sizeof operator with the pointer to get the size of the buffer begin pointed to, where-as with the const char[] version you can use sizeof on the array variable to get the memory footprint size of the array in bytes. So it really depends on what you're wanting to-do with the pointer or buffer, and how you want to use it.

For instance, doing:

void withPointer()
{
    const char *sz = "hello";
    std::cout << sizeof(sz) << std::endl;
}

void withArray()
{
    const char sz[] = "hello";
    std::cout << sizeof(sz) << std::endl;
}

will give you very different answers.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • 8
    I'd like to take this opportunity to point out that sizeof is not a function. – unwind Oct 26 '11 at 13:55
  • 3
    @unwind: technically, but my eyes get confused when parsing `std::cout << sizeof sz << std::endl;` because two identifiers in a row usually signifies a type declaration. `sizeof(sz)` my brain parses as just another function. – Mooing Duck Oct 26 '11 at 16:10
6

In general to answer these types of questions, use the one that's most explicit.

In this case, const char[] wins because it contains more detailed information about the data within -- namely, the size of the buffer.

tenfour
  • 36,141
  • 15
  • 83
  • 142
4

Just a note:

I'd make it static const char sz[] = "hello";. Declaring as such has the nice advantage of making changes to that constant string crash the program by writing to read-only memory. Without static, casting away constness and then changing the content may go unnoticed.

Also, the static lets the array simply lie in the constant data section instead of being created on the stack and copied from the constant data section each time the function is called.

  • 1
    I don't think casting awayy the const goes unnoticed very often – Mooing Duck Oct 26 '11 at 15:01
  • Sometimes it does. It's just a protection against Murphy. –  Oct 26 '11 at 15:04
  • @Fanael: so static const char[] behaves almost te same as const char*? There is only one copy and no overhead during initialisation? – rve Oct 26 '11 at 15:48
  • 1
    Yes, and you can still use `sizeof` on it and get the actual size of the array, as it still is, well, an array. `static` is a storage specifier that has nothing to do with the type. –  Oct 26 '11 at 15:51
  • I also found this: http://stackoverflow.com/questions/2096448/do-these-statements-about-pointers-have-the-same-effect/2097649#2097649 . It states that the pointer version may point to the same string if they are equal but the array version will always be unique, even when the strings are equal. – rve Oct 26 '11 at 18:22
  • I totally fail to see how crashing a program can be an advantage point. If you are writing a toy app then ok. If its a software that runs an important process, like the controlling hardware or something important, a crash could cost the user a lot of money or even cause accidents. – cauchi Jun 10 '22 at 15:09
2

If you use an array, then the data is initialized at runtime. If you use the pointer, the run-time overhead is (probably) less because only the pointer needs to be initialized. (If the data is smaller than the size of a pointer, then the run-time initialization of the data is less than the initialization of the pointer.) So, if you have enough data that it matters and you care about the run-time cost of the initialization, you should use a pointer. You should almost never care about those details.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Compiler probably optimises the two versions in to the same code. No need for array initialization at runtime. – David Heffernan Oct 26 '11 at 14:16
  • 3
    @DavidHeffernan: I don't think a compiler can produce the same code. With a const array, the user is allowed to cast away the constness and then should be able to write to the array - therefore the array needs to be placed in the writable memory. – Nemanja Trifunovic Oct 26 '11 at 14:38
2

I was helped a lot by Ulrich Drepper's blog-entries a couple of years ago:

so close but no cigar and more array fun

The gist of the blog is that const char[] should be preferred but only as global or static variable.

Using a pointer const char* has as disadvantages:

  1. An additional variable
  2. pointer is writable
  3. an extra indirection
  4. accessing the string through the pointer require 2 memory-loads
mirk
  • 5,302
  • 3
  • 32
  • 49
0

Just to mention one minor point that the expression:

const char chararr[4] = {'t', 'e', 'x', 't'};

Is another way to initialize the array with exactly 4 char.

Kemin Zhou
  • 6,264
  • 2
  • 48
  • 56