Question

const char* src = "hello";

Calling strlen(src); returns size 5...

Now say I do this:

char* dest = new char[strlen(src)];
strcpy(dest, src);

That doesn't seem like it should work, but when I output everything it looks right. It seems like I'm not allocating space for the null terminator on the end... is this right? Thanks

Was it helpful?

Solution

You are correct that you are not allocating space for the terminator, however the failure to do this will not necessarily cause your program to fail. You may be overwriting following information on the heap, or your heap manager will be rounding up allocation size to a multiple of 16 bytes or something, so you won't necessarily see any visible effect of this bug.

If you run your program under Valgrind or other heap debugger, you may be able to detect this problem sooner.

OTHER TIPS

Yes, you should allocate at least strlen(src)+1 characters.

That doesn't seem like it should work, but when I output everything it looks right.

Welcome to the world of Undefined Behavior. When you do this, anything can happen. Your program can crash, your computer can crash, your computer can explode, demons can fly out of your nose.

And worst of all, your program could run just fine, inconspicuously looking like it's working correctly until one day it starts spitting out garbage because it's overwriting sensitive data somewhere due to the fact that somewhere, someone allocated one too few characters for their arrays, and now you've corrupted the heap and you get a segfault at some point a million miles away, or even worse your program happily chugs along with a corrupted heap and your functions are operating on corrupted credit card numbers and you get in huge trouble.

Even if it looks like it works, it doesn't. That's Undefined Behavior. Avoid it, because you can never be sure what it will do, and even when what it does when you try it is okay, it may not be okay on another platform.

The best description I have read (was on stackoverflow) and went like this:

If the speed limit is 50 and you drive at 60. You may get lucky and not get a ticket but one day maybe not today maybe not tomorrow but one day that cop will be waiting for you. On that day you will pay and you will pay dearly.

If somebody can find the original I would much rather point at that they were much more eloquent than my explanation.

strcpy will copy the null terminated char as well as all of the other chars.

So you are copying the length of hello + 1 which is 6 into a buffer size which is 5.

You have a buffer overflow here though, and overwiting memory that is not your own will have undefined results.

Alternatively, you could also use dest = strdup(src) which will allocate enough memory for the string + 1 for the null terminator (+1 for Juliano's answer).

This is why you should always, always, always run valgrind on any C program that appears to work.

Yeah, everyone has covered the major point; you are not guaranteed to fail. The fact is that the null terminator is usually 0 and 0 is a pretty common value to be sitting in any particular memory address. So it just happens to work. You could test this by taking a set of memory, writing a bunch of garbage to it and then writing that string there and trying to work with it.

Anyway, the major issue I see here is that you are talking about C but you have this line of code:

char* dest = new char[strlen(src)];

This won't compile in any standard C compiler. There's no new keyword in C. That is C++. In C, you would use one of the memory allocation functions, usually malloc. I know it seems nitpicy, but really, it's not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top