Re: problems with free()



allanallansson911@xxxxxxxxx writes:
[...]

Since you posted to comp.lang.c.moderated rather than comp.lang.c,
it's going to take a long time before you see this response -- and
you'll see a lot of other responses along with it. comp.lang.c has
an unpleasantly high signal-to-noise ratio, but you'll get much
faster responses. I'll cc this followup to your e-mail, so you can
see it sooner -- but it will still take a while to see any corrections
to any mistakes I've made.

#include <stdio.h>
#include <stdlib.h>

int main() {

"int main(void)" is (slightly) better.

char* mystr = NULL;

No need to initialize mystr to NULL, since you immediately assign a
new value to it. In fact, you could just as easily put the malloc
call in the initializer.

mystr = (char*) malloc(100 * sizeof(char)); //I want to make room
for a 100 char long string seq.

Some software, somewhere along the path from your newsreader to
mine, wrapped this long line. Since you used a "//" comment, and it
wrapped in the middle of the comment, the result is a syntax error.
Using "/* ... */" comments in code you post to Usenet avoids
this problem. (It also makes your code a bit more portable; "//"
comments are a new feature in C99.)

This isn't incorrect (except that allocating 100 bytes will only
give you enough memory to store a string of length 99), but you're
making at least two common mistakes here. First, never cast the
result of malloc(). Second, sizeof(char) is 1 by definition.
See section 7 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

You can write the above as:

mystr = malloc(100);

Or you can collapse the declaration and the assignment into:

char *mystr = malloc(100);

if(mystr == NULL) {
printf("Could not allocate memory");
return 0;
}

Good, you're checking for malloc failure. Some suggestions, though:
Print the error message to stderr, not stdout. Terminate the
message with a "\n". Return EXIT_FAILURE rather than 0, to notify
whatever invoked the program that something went wrong. In fact,
I'd probably use exit() rather than return, in case the code later
is moved into a function other than main().

if (mystr == NULL) {
fprintf(stderr, "Could not allocate memory\n");
exit(EXIT_FAILURE);
}

(Actually, if this were in a function other than main, you'd want
that function to return a value to its caller that indicates
a problem, so the caller can decide how to handle the error.
But that's not very important for a small program like this.)

mystr = "test\0";

The "\0" is redundant; a string literal already has an implied '\0'
terminator. (There is a difference: "test\0" has *two* trailing '\0'
characters. But you're not making any use of that.) (There's one
obscure case where a string literal doesn't give you an implicit
trailing '\0', but it has nothing to do with what you're doing here.)

But the real problem (and this is what causes the symptom
you're seeing) is that you're doing a pointer assignment, not
an array assignment -- because C doesn't have array assignments.
The string literal "test" causes the compiler to create a static
array object containing the characters { 't', 'e', 's', 't' '\0' }.
The assignment copies the *address* of (the first character of) this
array into the pointer object mystr. The previous value of mystr
is lost -- which means that you've lost your only pointer to the
memory that you just allocated with malloc(). This is a memory leak.

If you wanted to *copy* the string, you'd have to use strcpy()
(for which you'll need a "#include <string.h>"):

strcpy(mystr, "test");

printf("mystr = '%s'\n\r", mystr);

The \r is quite unnecessary. stdout is opened in text mode,
which means that the implementation will do whatever translation is
necessary to turn the '\n' character into a proper line terminator
(perhaps "\n", perhaps "\r\n", perhaps something else entirely).
Incidentally, if you'd prefer to use double quotes to delimit the
string in your output, you can do it like this:

printf("mystr = \"%s\"\n", mystr);

free(mystr); //Its here that the runtimeerror occurs

As we've seen, mystr points to the string literal, not to the memory
allocated via malloc. Passing this pointer value, or anything
other than a pointer to memory allocated by malloc (or calloc or
realloc), invokes undefined behavior. You're lucky that you got a
run-time error; it could have failed silently, leaving you unaware
that there was a problem.

return 0;
}

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • Re: Does malloc() reuse addresses?
    ... if i allocate some memory with malloc() and later free it (using ... allocate memort at the same starting address and will return the same ... In this example, if an instance is freed, and a pointer to it becomes ... If you are doing what you say with the instance array, ...
    (comp.lang.c)
  • Re: Are the following 2 code statements equivalent
    ... In the calloc() case, the ... is not allowed to allocate some smaller amount. ... You call memsetwithout checking the result of the malloc() call. ... If mallocfails, it returns a null pointer, and the call to memset ...
    (comp.lang.c)
  • Re: problems with free()
    ... Don't cast the returnvalue of malloc() in C. ... multiples of the size of a char. ... Here lies the real error in your code: you are assigning to a pointer ... The reason is that 'mystr' was not allocated using mallocbut is the ...
    (comp.lang.c.moderated)
  • Re: malloc inside function (I know... I *did* search google first ;)
    ... > and the return value of malloc should ALWAYS be checked for NULL, ... Functions that allocate memory commonly return a pointer to the memory ... and then the float * return is certainly more natural ...
    (comp.lang.c)
  • Does malloc() reuse addresses?
    ... if i allocate some memory with malloc() and later free it (using ... allocate memort at the same starting address and will return the same ... int isInstanceValid ... In this example, if an instance is freed, and a pointer to it becomes ...
    (comp.lang.c)

Loading