Here’s a simplified version of a function I wrote just now:
int foobar(char * foo) {
puts(type);
struct node * ptr = (struct node *) malloc (sizeof(struct node));
puts(type);
memset(ptr, 0, sizeof(ptr));
ptr=head;
return head->id;
}
Here node is just a struct declared as a node in the linklist, which contains a char * and a pointer to the next node. However, I realize that the malloc() here is corrupting my input char * foo.
Why would malloc() corrupt my input char pointer? Also, how could I resolve the issue here? Now I am just copying the content of that pointer to a local array, but this is too hacky, even for my taste (which isn’t the best).
Thanks for any inputs!
EDIT: Well, here’s more real code:
void foobar(char * type) {
puts(type); <-- here it's a long string about 30 char
struct node * ptr = (struct node *) malloc (sizeof(struct node));
puts(type); <- chopped of, 10 left with some random thing at the end
}
Hope the problem is clear now! Thanks!
EDIT:
Here’s how type got initialized:
type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);
Thanks!
The apparent corruption would happen because
typeorfoopoints at already freed memory whichmalloc()gives back to you for a different use.Once you’ve released the memory, you cannot continue to use it.
You also have a problem because you allocate to
ptr, then wipeptrout with:You might have meant:
but you would probably need to set
ptr->next = head;before that. Of course, this is speculation since you’ve not shown the type definitions.It also isn’t obvious why you return
head->idinstead of eitherheadorptr. Unfortunately, we don’t have enough information to say “that is wrong”; it is just not usual.Commentary on 2nd Edit
There is some of the trouble. You’ve gone trampling on memory that you have no business trampling on.
The first two lines are fine; you duplicate a string. Note, though, that
typeis a pointer to 6 bytes of memory, andtempTypeis a pointer to 7 bytes of memory.The disaster strikes in the third line.
type + strlen(type)is pointing to the null byte at the end of thetypestring. You then write 1 byte oftempTypeover it more or less legitimately; you don’t have a null terminated string any more, but the first byte is within bounds. The second and subsequent bytes are written in space that is not allocated to you, and that probably contains control information about memory allocation.Writing out of the bounds of the allocated memory leads to ‘undefined behaviour’. Anything can happen. On some machines, particularly with a 64-bit compilation, you might get away with it altogether. On most machines, and especially 32-bit compilations, you’ve wrecked your heap memory and something somewhere (typically somewhat distant from this spot) will run into trouble because of it. That is the nature of memory abuse; the place where it occurs often appears to work and it is some other innocent piece of code that suffers from the problems caused elsewhere.
So, if you want to concatenate those strings, you need to do something like:
I’ve omitted error checking. You should check the allocations from
strdup()andmalloc()to ensure that you got memory allocated. Some might argue that you should usesnprintf(); it was a conscious decision not to do so since I’ve calculated the necessary space in the previous line and allocated sufficient space. But you should at least consider it. If you have not ensured that there is enough space available, then you should usesnprintf()to avoid buffer overflows. You would also check its return value so you know whether the information was all formatted or not. (Also note that you have 3 pointers to free, or pass off to some other code so that the allocated memory is freed at an appropriate time.)Note that on Windows,
snprintf()(or_snprintf()) does not behave the way specified by the C99 standard. Frankly, that’s not helpful.