Reputation: 67224
note: please suppress comments about "C++? Use std::string!". This question is using C strings but is more about memory management than strings in general.
I have this function
char* strclone( char* src )
{
char* dst = (char*)malloc(strlen(src+1));
strcpy(dst,src);
return dst;
}
The function should work to allocate a new pointer (in strclone
), write the string in src to it, and return the address of the new string.
However, when the string is free
d, some time later in the program:
str = strclone( some_str_variable );
// ..code..
free( str ) ; //! ERROR!
The error reads:
Debug Error! Program: C:\... HEAP CORRUPTION DETECTED: after Normal block (#39713) at 0x090CC448. CRT detected that the application wrote to memory after end of heap buffer.
The error occurs at the line where I call free( str )
in the program. If I change the assignment of str to this:
str = (char*)malloc( strlen( some_string_variable ) +1);
strcpy( str, some_string_variable ) ;
//...
free( str ) ; //fine now
Then there is no bug, the program functions perfectly.
Why does the strclone
function not work as expected?
Upvotes: 1
Views: 746
Reputation: 372724
I believe that the problem is that you've written
(char*)malloc(strlen(src+1));
Notice that in the call to strlen
, you have written
strlen(src + 1)
instead of
strlen(src) + 1
This first line says "the length of the string starting one character past src
," which is the length of the string minus one (or total garbage if the string is empty). The second one is the one you want - the length of the string plus one for the null terminator. If you use the first version, then in the line
strcpy(dst,src);
You will end up writing past the end of the buffer, leading to the dreaded Undefined Behavior. In your case, this was manifesting itself with a heap corruption error when you try to free the block, which makes sense because you have indeed corrupted the heap!
Try moving the +1 out of the parentheses and see if it fixes things.
Alternatively, most compilers ship with a nonstandard function called strdup
that does exactly what your above function attempts to do. You might want to consider just using that instead.
Hope this helps!
Upvotes: 15
Reputation: 272467
strlen(src+1)
is not the same as strlen(src)+1
. So you are overwriting the bounds of your array by two elements when you do to the strcpy
.
So I think the following is justified: C++? Use std::string
!
Upvotes: 4
Reputation: 1904
The error happens because you are actually writing past the allocated memory. change your malloc line to this:
char* dst = (char*)malloc(strlen(src)+1);
Because in your original implementation, you're advancing the pointer by 1, and then you pass that to strlen(), which will give you the lenght of the string-1. Since you also need the NULL at the end, you're actually off-by-2.
Upvotes: 0
Reputation: 4934
I believe you should have typed
char* dst = (char*)malloc(strlen(src) + 1);
instead of
char* dst = (char*)malloc(strlen(src+1));
Upvotes: 0