简体   繁体   中英

What is the difference between char array[] and char *array?

What is the difference between doing these two options, and why is the second type deprecated in C++?

char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};

char *hello = "hello";

But in correct c++ the second should be:

const char *hello = "hello";

For the most part I guess you are never going to change "hello", but why can't you change this memory if you wanted to?

char hello[] = {'h', 'e', 'l', 'l', 'o', '\\0'};

This creates an array of 6 bytes in writable memory (on the stack if this is inside a function, in a data segment if directly at global scope or inside a namespace), to be initialised with the ASCII codes for each of those characters in turn.

char *hello = "hello";

"hello" is a string literal , which typically means:

  • the OS loader code that loads your program into memory and starts it running will have copied the text "hello\\0" from your executable image into some memory that will then have been set to be read only, and

  • a separate variable named "hello" - which is of whatever size pointers are in your program (eg 4 bytes for 32-bit applications, 8 for 64-bit) - will exist on the stack (if the line above appears inside a function) or in writable memory segment (if the line is at global or namespace scope), and the address of the former textual data will be copied into the hello pointer.

  • you can change hello to point somewhere else (eg to another language's equivalent text), but normally shouldn't try to change the string literal to which the above code points hello ... see below.

But in correct c++ the second should be:

const char *hello = "hello";

Yes - that's much better. For backwards compatibility, C++ has historically allowed non- const pointers to string literals, but actually modifying them wasn't guaranteed to be possible. Some compilers always, or can optionally (when asked by command line arguments), put string literals in writable memory. But, even if they are writable, changing them leads to lots of potential for errors. Say you have code like this and compiler flags to allow it to compile:

char* end = "end";
if (mixed_case_mode) end[0] = 'E';
if (s == "end") ...;

Then some completely unrelated code that does this...

std::cout << "this is the " << (x ? "start": "end");

...might start printing "End" if all mentions of "end" shared the same memory - a common and desirable optimisation. Turning this off can be quite wasteful, and while it allows this hackery to work with less unintended side effects to unrelated uses of the text, it's still very hard to reason about the code and debug when if (s == "end") might not actually be comparing s to "end" .

When you use [] you create an array which is a collection of items, chars in this case.

As you probably are aware, using * creates a pointer which might appear to be the same thing but is simply a single value (a memory address).

In essence the array creates a variable as large as the data where as the pointer just creates a 8 byte variable which contains the memory location of the string constant.

If you want a string you can change, just use

char hello[] = "Hello";

This is legal and means exactly the same as your first statement. You can also reserve extra space, since you're writing you might want to store a bigger string later:

char hello[100] = "Hello";

What is the difference between doing these two options

The first declares an array containing those characters. The second declares a pointer to a string literal: a static constant array containing the same characters. Or it would, if you were allowed to do that.

why is the second type deprecated in C++?

It isn't: it's forbidden, since the string literal is constant. Before C++11, it was allowed, but deprecated, to avoid breaking ancient code that didn't use const . In either case, attempting to modify the literal gives undefined behaviour.

why can't you change this memory if you wanted to?

Because string literals are constant. If you want some memory that you can change, you'll have to create your own array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM