119

Can anyone explain me what is a difference between these lines of code

char *p = "String";
char p2[] = "String";
char p3[7] = "String";

In what case should I use each of the above ?

Mehdi Charife
  • 722
  • 1
  • 7
  • 22
summerc
  • 1,871
  • 4
  • 18
  • 17
  • 31
    Well that last one is a buffer overflow, so that's nice. – Dan Jan 04 '12 at 18:57
  • 3
    You third example should be `p3[6]`: you must account for the final 0 – fge Jan 04 '12 at 18:57
  • 22
    @fge: needs 7 in fact. – Mat Jan 04 '12 at 18:58
  • 1
    @Dan compilation error, rather – littleadv Jan 04 '12 at 18:58
  • Also: http://stackoverflow.com/questions/1880573/c-difference-between-char-var-and-char-var http://stackoverflow.com/questions/3268292/need-some-help-with-c-programming http://stackoverflow.com/questions/3862842/difference-between-char-str-string-and-char-str-string – interjay Jan 04 '12 at 19:01

4 Answers4

50

This link should satisfy your curiosity.

Basically (forgetting your third example which is bad), the different between 1 and 2 is that 1 allocates space for a pointer to the array.

But in the code, you can manipulate them as pointers all the same -- only thing, you cannot reallocate the second.

Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
fge
  • 119,121
  • 33
  • 254
  • 329
  • guys, before you bookmark the link that fge posted, be aware that FAQ website has been updated to this http://c-faq.com and the specific link posted to this http://c-faq.com/aryptr (2.1,2.2) but without changes. Just in case. – Yannis Dran Jan 12 '19 at 16:08
49

Strings in C are represented as arrays of characters.

char *p = "String";

You are declaring a pointer that points to a string stored some where in your program (modifying this string is undefined behavior) according to the C programming language 2 ed.

char p2[] = "String";

You are declaring an array of char initialized with the string "String" leaving to the compiler the job to count the size of the array.

char p3[5] = "String";

You are declaring an array of size 5 and initializing it with "String". This is an error be cause "String" don't fit in 5 elements.

char p3[7] = "String"; is the correct declaration ('\0' is the terminating character in c strings).

http://c-faq.com/~scs/cclass/notes/sx8.html

Joe
  • 159
  • 3
  • 14
ob_dev
  • 2,808
  • 1
  • 20
  • 26
22

You shouldn't use the third one because its wrong. "String" takes 7 bytes, not 5.

The first one is a pointer (can be reassigned to a different address), the other two are declared as arrays, and cannot be reassigned to different memory locations (but their content may change, use const to avoid that).

littleadv
  • 20,100
  • 2
  • 36
  • 50
  • 5
    `char p3[5] = "String";` while dangerous is not wrong and it is valid in C (but not in C++) – ouah Jan 04 '12 at 19:05
  • 6
    @ouah - it is wrong. It may pass compilation, but it is nevertheless **wrong**. – littleadv Jan 04 '12 at 19:06
  • 4
    this is a strictly conforming definition for an object. A strictly conforming program is not "wrong" in terms of C. – ouah Jan 04 '12 at 19:15
  • 6
    @ouah Blatant runtime errors are wrong. – Chris Eberle Jan 04 '12 at 19:47
  • @Chris, Depends on the other statements doesn't it. There isn't necessarily a runtime error. – Pacerier Dec 09 '14 at 03:59
  • @Pacerier it depends on many things, but at the end of the day it's still considered undefined behavior. Undefined behavior is not deterministic, which is still a runtime error even if the program doesn't crash from it. – Chris Eberle Dec 14 '14 at 22:54
  • @Chris, That's provided the code even gets **run**-ed at runtime. Surely **compiling** that code alone wouldn't give you undefined behavior. – Pacerier Dec 16 '14 at 14:27
  • @Pacerier undefined always refers to runtime behavior. It will indeed compile. – Chris Eberle Dec 18 '14 at 02:43
  • @Chris, And that's why we wouldn't have undefined behavior is that compiled code doesn't get run, for example when its surrounded within an `if` statement that doesn't evaluate to true. – Pacerier Dec 18 '14 at 02:49
  • @Pacerier I really am having a hard time following this conversation. No, runtime errors don't occur if you skip over the problematic code. – Chris Eberle Dec 18 '14 at 04:02
  • @Chris, Yes, that's what I've been saying all along... You stated *"Blatant runtime errors are wrong."* so I stated *"Depends on the other statements doesn't it. There isn't necessarily a runtime error."*. Runtime errors don't occur if you skip over the problematic code so depending on the other statements, there isn't necessarily a runtime error. – Pacerier Dec 19 '14 at 02:35
  • 10
    @Pacerier please stop being intentionally pedantic. You know very well that my statement doesn't mean 'renders the program useless'. The surrounding code is irrelevant. If I write to memory that I shouldn't write to, that's bad behavior. That's a bug. Even if no one notices, that's still a bug. Even if my code never runs, there's still a bug present. The bug may not run, but that doesn't mean my code is bug-free. Stop with the games, you're not being clever. – Chris Eberle Dec 19 '14 at 04:10
7
char *p = "String";   means pointer to a string type variable.

char p3[5] = "String"; means you are pre-defining the size of the array to consist of no more than 5 elements. Note that,for strings the null "\0" is also considered as an element.So,this statement would give an error since the number of elements is 7 so it should be:

char p3[7]= "String";
gsamaras
  • 71,951
  • 46
  • 188
  • 305
SKM
  • 959
  • 2
  • 19
  • 45