1

In this code:

int length = atoi(argv[1]);
char *tab = malloc(length * sizeof(char));
memset(tab, '-', length);
puts(tab);

no matter what value I passing to argv[1], the output is correct. For example, for argv[1] = "5" i get ----- (five hyphens).

I'm wondering how puts() can find the end of input string when I have not put a '\0' at the end of my array of chars.

byxor
  • 5,930
  • 4
  • 27
  • 44
myschu
  • 91
  • 1
  • 8

3 Answers3

5

What @aschepler said. I am guessing that something — either the operating system or your C runtime or startup code — is zeroing out the memory before you malloc it. As a result, your string is null-terminated by virtue of the fact that you didn't overwrite the \0 bytes that were already there. Don't assume this will always work!

Edit Different compilers, OSes, and libraries initialize memory differently. This question and its answers, and likewise this one, give some examples of initialization patterns and other patterns written to memory to assist debugging. Turns out at least one compiler (IBM XLC) lets you choose the value for uninitialized automatics.

cxw
  • 16,685
  • 2
  • 45
  • 81
  • 1
    Just a thought, but I wonder how many bugs would be caught earlier if memory was `\1`'d out rather than zeroed out (or just filled with non-zero garble, for that matter). – byxor May 06 '17 at 13:12
  • 1
    @myschu If this answer, or another, resolved your question to your satisfaction, would you please hit the checkmark next to that answer to accept it? That will help future readers of the question know what worked for you, and will clear the question off the no-accepted-answer lists. You and the person whose answer you accept will also get reputation points :) . – cxw Jun 28 '17 at 17:05
1

Try values like 0, 1, 1000, 1000000, 1000000000, 1000000000000, -1.

One steals a few things from a store and does not get caught, does that make stealing OK? Try stealing the whole store and see if it "works".

puts() requires a string, that means a null character certainly ends it - else it is not a string. If code breaks the rules, puts() is not obliged to behave in a certain fashion. It is undefined behavior (UB).


BTW, code should also check if tab != NULL before using it in memset(tab, '-', length);

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

As stated by @cxw above, you are just lucky (or your system simply zeroes your memory upon malloc) that your string holds a \0 after its content.

I would also like to add that you should however not rely on such methods as it makes your program unstable and prone to crashs. In this case, you end up having an invalid reading error, but in case your malloc would have been larger, you'd be reading uninitialized memory.

You may want to use tools such as Valgrind to spot memory issue. Always keep in mind that any memory error should be fixed before publishing your program as crashs are very likely depending of the platform the program is executed on, but also because such errors could be maliciously used.

Ra'Jiska
  • 979
  • 2
  • 11
  • 23