0

1a) There is this code

char *p;
p[0]='a';
p[1]='b';
printf("%s",p);

When i run this program on ideone.com compiler: c++ 4.3.2, it displays "RUNTIME ERROR" every single time i run it.

1b). however when i edit this code to

char *p;
//allocate memory using malloc
p[0]='a';
p[1]='b';
printf("%s",p);

It correctly runs and prints "ab" . shouldn't it require the p[2]='\0' at the end?

2)

char *p;
p="abc"
printf("%s",p);

this correctly runs and prints "abc" . why does this work without allocation.

Can anyone please explain the rules regarding string storage ?

guitar_geek
  • 498
  • 2
  • 9
  • 19
  • 1b): depends on how you allocate your memory, if what `p` points to hasn't been zeroed and isn't at least 3 chars long then you have UB. 2): see this http://stackoverflow.com/questions/718477/string-literals – user657267 Aug 12 '14 at 08:45

3 Answers3

4

1a) undefined behavior because you dereference a non initialized pointer

1b) undefined behavior since you call printf with %s for a non null terminated string

2) works ok: there is an allocation, it just is a string literal (you can't modify it, it is stored in the read-only portion of the program : you should declare it const char* for that reason)

Note:

In C++, use std::string and std::cout .

quantdev
  • 23,517
  • 5
  • 55
  • 88
2

In the first example you declare a pointer to char and then you assign values to undefined locations in memory. Undefined because its what the uninitialize p pointer points to. You need to allocate memory for the sequence (with new[] in C++, not malloc). If you do not put a '\0' at the end, printing will stop at the first 0 encountered in memory.

In the third example you are declaring a pointer to char and initialize its value with the address of the literal string "abc". That is stored in the (read-only) data section in the executable and that gets map to the process address space. So that's a valid pointer and your printing works.

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
1

1a) here you don't allocate memory, so the p pointer points to a random place, therefore causing segfault when you write that random location

1b) if you allocate memory manually with malloc, it will work correctly. If the allocated memory contains 0s, you don't have to add it manually (but you should, because you can't count on the zero filling)

2) here you assign the p pointer to the string literal "abs", so it will point to it, and the allocation is done by the compiler

glezmen
  • 554
  • 2
  • 5
  • 1b) so, you're saying there must be a 0 present after the 'b' ? – guitar_geek Aug 12 '14 at 13:14
  • @guitar_geek yes, otherwise you'd see garbage, like "ab@#$@#(*GDFS". To be sure that will not happen, add p[2] = '\0'; (and don't forget to allocate enough memory, in this case 3*sizeof(char)) – glezmen Aug 12 '14 at 13:24