C - strcpy with malloc size less than argument's size

208 views Asked by At
char* init_array()
{
    const int size = 5;
    char *p = (char*) malloc(size * sizeof(char));
    strcpy(p, "Hello, world! How are you?");

    return p;
}

with size = 5, malloc should get 5 free chars from memory, but given string does not fit into 5 chars, yet it works.

My question is why? First I thought the result would get truncated but p is the fully string, not just "Hello" or "Hell\0"

I'm using GCC on Linux. Is it related to the compiler or it is standard stuff?

3

There are 3 answers

2
Iharob Al Asimi On BEST ANSWER

It's called undefined behavior, since it's undefined sometimes it works. Yes you can write past a memory block in c, but that's illegal because it invokes undefined behavior, the behavior is therefore not predictable and your program might or might not work.

What you expect from strcpy() doesn't happen because strcpy() copies as many characters as it finds before the '\0' terminating byte, it doesn't care if the destination buffer is large enough, that's something you must be responsible about.

If you want to copy an exact number of bytes (let's say 5) you can use

memcpy(p, "Hello, this string is very large but it doesn't matter", 5);

but beware that p is not a valid string after that, because it has no terminating '\0'.

You also have 2 other common bad practice that new c programmers do

  1. You don't need to cast the return value from malloc().

  2. You don't need to use sizeof(char) because it's 1 by definition.

So,

p = malloc(size);

should be enough to allocate space for a size - 1 characters string.

0
Spikatrix On

What you are experiencing is a buffer overflow

In short, you write to invalid memory addresses invoking Undefined Behavior. Anything can happen.

0
haccks On

It seems that it worked but in fact your code invokes undefined behavior. You are writing data to unallocated memory location.

You should note that in

strcpy(str1, str2);  

strcpy has no way to check whether the string pointed to by str2 will fit into the character array str1. In your case it will continue to copy the characters from "Hello, world! How are you? to past the array p points to.