4

While implementing infix to postfix and vice versa algorithms

I found,

char * str = (char*) malloc(1);
strcpy(str,str2);

this works even if str2 is more than 1 characters(20 chars or more).

I did not get any warning or runtime error.

How is this possible?

Note:

I did not get garbage also.

I always get required result irrespective of str2.

glglgl
  • 89,107
  • 13
  • 149
  • 217

2 Answers2

8

The reason this works is that C has unchecked memory access. strcpy/strcat have NO IDEA how much memory is at the other end of the pointer you gave them. They just assume you know what you are doing, and go for it.

As to why you didn't see a problem: Well, they wrote into that memory. There's nothing stopping them from writing beyond what you've allocated, so they do. So when you look at it later, it's fine. So what's going on? They wrote over something else!

Might be they wrote over something else that was already allocated, might be they wrote over unallocated space, might be that you got lucky and they wrote over something that nothing cares about.

Might be they wrote over internal structures, and some time later you'll get malloc crashing.

If you know that you've allocated enough buffer somehow, it's OK to use these functions, but in most cases (and especially if the thing being copied came from the user), you'll want to look at strncpy. But be careful that one has some other traps for the unwary.

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
  • 4
    Even `strncpy()` doesn't always do what one thinks it does. E. g. it skips the terminating `\0` if the string is longer than the size. – glglgl Feb 15 '14 at 17:08
3

That's why it is not recomended to use strcat and strcpy functions. Better to use strncat and strncpy. But they also need some cautions before use because strncpy and strncat is also not safer to use.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 2
    +1 for "...cautions before use". I tend to use a more useful, self-crafted function instead, which puts the end-`\0` under all circumstances and, as well, returns the "new" dest pointer instead of the original one, which then can be used for further steps, obsoleting a replacement for `strcat()`. – glglgl Feb 15 '14 at 17:10
  • @glglgl; Most of the time I do the same :) – haccks Feb 15 '14 at 17:17
  • 1
    @glglgl: I tend to use a library function that does full buffer management for me at the same time, using an efficient memory allocation strategy as well as keeping track of the length of what is used as well. Keep a little metadata, use the right algorithm, it's amazing how much faster things go! – Donal Fellows Feb 16 '14 at 07:35