0

here's a code that allocates some memory and copies a string into it.

#include <stdio.h> #include <string.h> #include <stdlib.h> int main(){ char *t ="your_char"; char *s = (char*)malloc(9); memcpy(s,t,9); printf("%s\n",t); printf("%s",s); return 0; } 

now the output is

your_char your_char☺╚ 

And that is what I am unable to understand. If I change to memcpy(s,t,10), then there is no garbage value at the end.

I assume it is because of null terminator that also gets copied in second case. But why is there an empty place at all when I have only allocated 9 bytes and they are already occupied by the characters I copied.

11
  • 1
    C strings have a zero byte that marks the end of the string. So "your_char" takes 10 bytes when you count the zero byte, and you need to malloc 10 bytes, and copy all 10 bytes. Otherwise, printf doesn't know where the string ends. printf has no way of knowing the number that you passed to malloc. All it does is look for the zero byte to know where the string ends. Commented Dec 1, 2020 at 18:02
  • 1
    There is no guarantee that the code will fail if you overrun the allocated space, any more than you get arrested every time you break the law. You got away with it today but might not tomorrow. There wasn't an "empty place": there was no competition for it at that moment and it happened not to break anything. Commented Dec 1, 2020 at 18:12
  • 1
    The processor does what it is told to. If it breaks something, the task fails, and if it doesn't, the mistake can go unnoticed. If you stick to the language rules, then you don't risk failure. Commented Dec 1, 2020 at 18:20
  • 2
    Because there was no nul terminator copied, when you tried to print the string, the processor continues to print whatever it finds until one of two things happens: it finds a random 0 in memory, or it tries to read memory that it is not allowed to read. Commented Dec 1, 2020 at 18:32
  • 1
    Trying to read beyond the end of the allocated memory has undefined behavior. The worst form of undefined behavior is the program doing just what you expected it to do (because you still have a bug but it's going to be hard to detect). The behavior may be either consistent or inconsistent. You can't draw any real conclusions from seeing it behave the same way twice. Commented Dec 1, 2020 at 20:18

1 Answer 1

2

A string is a null terminated array of characters (a "null character" is the one that has the numeric value of 0). The null character marks the end of the string, If an array doesn't have a null character in it, it is not a string. In particular, you cannot printf it with the %s specifier, because printf has no idea where it ends.

String literals always have one automatically, for example, "your_char" has ten characters in it and not nine. If you allocate strings dynamically, you should always account for the extra character.

Sign up to request clarification or add additional context in comments.

7 Comments

you are right that "your_char" has 10 characters but I only allocated 9 bytes to s. If I had done char *s = (char *)malloc(strlen(temp)*sizeof(char)+1) then it may have mattered but I manually specified 9 bytes then how is s pointing towards 9 bytes+empty byte.
run this code : char tabstr[] = "your_char"; printf("size in bytes of tabstr:%d",sizeof(tabstr));
@mr.loop "s pointing towards 9 bytes+empty byte" No, it doesn't. You only allocxated 9 bytes, so that;s what s points to. There is nothing beyond these 9 bytes.
mr.loop What s points to is a linear memory address where you can modify at most 9 consecutive chars. Any modification by you before or after that 9 chars is a violation the malloc() contract and MAY get you in trouble.
@mr.loop you should not only allocate 10 characters, but also copy 10 characters.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.