groove
groove

Reputation: 283

How to clear a char* passed to a function in C?

How can i make a function to clear a C string and/or free the allocated memory? Why the following code does not work?

void freeStr(char** str) {
    free(*str);
}
int main() {
    char* str = "some string";
    freeStr(&str);
    printf("%s", str);
    return 0;
}

Upvotes: 3

Views: 39588

Answers (5)

Anirudh Ramanathan
Anirudh Ramanathan

Reputation: 46778

The string you allocated is in the CONST_DATA section (cannot be modified) and hence, you cannot call free on it.

That part of memory is allocated at compile time and is read only. That part of memory still holds "some string\0"

The CONST_DATA section, in assembly is like the data-segment (DS), which contains global and static (read-only) variables initialized at compile time itself. They do not change during runtime, and remain allocated to the running program.

Upvotes: 4

http://en.cppreference.com/w/c/memory/free

void free( void* ptr );

Deallocates the space previously allocated by malloc(), calloc() or realloc(). If ptr is null-pointer, the function does nothing.

Your string is not allocated with any of these functions. I think is this way.

void freeStr(char **str) {
    *str = NULL;
}
int main() {
    char* str = (char *)"some string";
    printf("Before: %s\n", str);
    freeStr(&str);
    printf("After: %s\n", str);
    return 0;
}

Upvotes: 2

Chimera
Chimera

Reputation: 6038

You might find it helpful to go over the C FAQ - malloc section.

As others have noted, you can't free or modify string literals as they are usually placed in read only sections of memory. However, if you wish to clear and free() dynamically allocated memory, you'd do something like the following:

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

#define LENGTH  20

void freeStr(char **str)
{
    free( *str );
    *str = NULL;   
}

int main() {

    char *str = malloc( sizeof(char) * LENGTH);

    // clear that allocated memory
    memset( str, 0x00, LENGTH );

    // Put some text into the memory
    strncpy( str, "Some text", LENGTH-1 );

    printf("Before: %s\n", str);


    freeStr(&str);
    // string is now NULL and the memory is free.
    printf("After: %s\n", str);

    return 0;
}

Upvotes: 4

Max DeLiso
Max DeLiso

Reputation: 1244

The answers are pretty good, but there are a few points that they've missed or omitted. Your question is also slightly vague.

If you want to clear a C string you overwrite the memory space that it points to with null bytes. You can only free() a C string that has been allocated by the heap allocator via a call to one of the heap allocator functions such as malloc(), calloc() or realloc() etc.

So if you allocated a string using malloc(), or one of the other heap allocation functions, like so and then copied a string into it, you could clear it by calling memset(), but you would still then have to call free() to release that memory back to the heap.

For example:

char* strPtr = malloc(32); // allocate 32 bytes of storage off the heap
strcpy(strPtr, "test");    // copy a string into the newly allocated block on the heap
memset(strPtr, 0, 32);     // clear the allocated block
free(strPtr);              // return the allocated block to the heap

Also, note that C uses block scope and you do not have to explicitly deallocate arrays which were declared with the default storage class, auto, as they are popped off of the stack frame when that block goes out of scope.

void foo() {
    char strArray[32];          // this is a stack allocation
    strcpy(strArray, "test");   // copy a string onto the stack
    return;                     // no call to free() required
}

Finally, yet another method of allocation is static. When you use the declaration:

char* str = "literal string";

The space for the string "literal string" resides in a statically allocated segment which should never be written to. On some platforms, you will get a segfault if you try to write to that memory segment. You should not attempt to clear memory blocks that were statically allocated as there is no guarantee that the segment which they are mapped into is writable.

Upvotes: 3

eq-
eq-

Reputation: 10096

You can neither free nor clear the memory of the array that a string literal denotes.

However, to lose access to it, all you need is to change the pointer you've stored its address in:

str = NULL; // in main
// or
*str = NULL; // in freeStr

Upvotes: 10

Related Questions