Home:ALL Converter>How To Free Allocated Memory From Another Function

How To Free Allocated Memory From Another Function

Ask Time:2012-08-03T03:29:45         Author:Keith Miller

Json Formatter

I wrote the following code today to experiment with returning pointers to allocated memory. The program works fine but I do have a few questions:

  1. To allocate the memory for the return value of rmch I use realloc. I understand the function and what it does for the most part I'm just quite not sure what the point of (char *) in the line ret = (char *) realloc(ret, c * sizeof(char)); I understand that realloc(ret, c * sizeof(char)); resizes the allocated memory to #c chars, but what does the (char *) part do?

  2. I do not free the allocated memory that ret points to anywhere, but I do free a pointer to ret which is called in my main function. What is happening to the allocated memory? If it is not being freed how would I go about freeing it?

Code

#include <stdio.h>
#include <stdlib.h>
char* rmch(char *str, char ch)
{
    char *ret = NULL;
    int c = 0, i;

    for(i = 0; str[i] != '\0'; i++)
    {
        if(str[i] != ch)
        {
            c++;
            ret = (char *) realloc(ret, c * sizeof(char));
            ret[c - 1] = str[i];
        }
    }
    ret[c] = '\0';
    return ret;
}

int main(void)
{
    char *foo = rmch("f o o", ' ');

    printf("%s", foo);
    free(foo);
    return 0;
}

Author:Keith Miller,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/11784490/how-to-free-allocated-memory-from-another-function
ardent :

Freeing Foo in main will free the ret you've realloc'd in rmch.\n\nThe reason being is free() goes to the address specified by the pointer which is returned by rmch.\n\nAlso, as you have tagged this post with the \"C\" tag, you should never cast the return value of allocations. void *'s are automagically, implicitly promoted to whatever they are stored in, provided they were given the correct byte sizes during allocation.\n\nAs an aside, you should never directly store any allocated memory directly into the pointer you are using/will be using as this can lead to memory leaks if the pointer returned is NULL and you were still pointing to old memory.\n\nBetter to do this:\n\ntemp = realloc();\nif( temp == NULL)\n{\n printf(\"realloc failed to reallocated memory!\");\n return NULL;\n}\nret = temp;\n\n\nAnd then you would need to check for a NULL return in your main as well.",
2012-08-02T19:31:39
TOC :

Still one more problem on your code, when you run it with valgrind, you got something like this:\n\ntoc@UnixServer:~$valgrind --leak-check=full --show-reachable=yes ./realloc_pb\n==17077== Memcheck, a memory error detector\n==17077== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.\n==17077== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info\n==17077== Command: ./realloc_pb\n==17077== \n==17077== Invalid write of size 1\n==17077== at 0x80484BF: rmch (realloc_pb.c:19)\n==17077== by 0x80484E3: main (realloc_pb.c:25)\n==17077== Address 0x41b709b is 0 bytes after a block of size 3 alloc'd\n==17077== at 0x402896C: realloc (vg_replace_malloc.c:525)\n==17077== by 0x804848A: rmch (realloc_pb.c:14)\n==17077== by 0x80484E3: main (realloc_pb.c:25)\n==17077== \n==17077== Invalid read of size 1\n==17077== at 0x402903D: __GI_strlen (mc_replace_strmem.c:284)\n==17077== by 0x4098739: puts (ioputs.c:37)\n==17077== by 0x4050112: (below main) (libc-start.c:226)\n==17077== Address 0x41b709b is 0 bytes after a block of size 3 alloc'd\n==17077== at 0x402896C: realloc (vg_replace_malloc.c:525)\n==17077== by 0x804848A: rmch (realloc_pb.c:14)\n==17077== by 0x80484E3: main (realloc_pb.c:25)\n==17077== \nfoo\n==17077== \n==17077== HEAP SUMMARY:\n==17077== in use at exit: 0 bytes in 0 blocks\n==17077== total heap usage: 3 allocs, 3 frees, 6 bytes allocated\n==17077== \n==17077== All heap blocks were freed -- no leaks are possible\n==17077== \n==17077== For counts of detected and suppressed errors, rerun with: -v\n==17077== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 11 from 6)\n\n\nCause you need to allocate more room for the null terminated char, so modify this also:\n\ntemp = (char *) realloc(ret, (c + 1) * sizeof(char)); // It's better to use temp pointer as suggested by ardent sonata\n\n\nThe last thing is about the casting malloc or realloc functions it's not really necessary, it's useful for the compiler in case you forgot to add the correct header (stdlib.h), so he can warn you (http://c-faq.com/malloc/mallocnocast.html).\n\nHope this help.\n\nRegards.",
2012-08-02T20:55:06
yy