3

如何创建一个函数来清除 C 字符串和/或释放分配的内存?为什么下面的代码不起作用?

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

5 回答 5

10

您既不能释放也不能清除字符串文字表示的数组的内存。

但是,要失去对它的访问权限,您只需更改存储其地址的指针:

str = NULL; // in main
// or
*str = NULL; // in freeStr
于 2012-09-05T22:58:12.187 回答
4

您可能会发现阅读C FAQ-malloc 部分会有所帮助。

正如其他人所指出的,您不能释放或修改字符串文字,因为它们通常放置在内存的只读部分中。但是,如果您希望清除和free()动态分配的内存,您可以执行以下操作:

#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;
}
于 2012-09-06T00:06:01.737 回答
4

您分配的字符串位于CONST_DATA部分(无法修改),因此您不能对其调用 free 。

那部分内存是在编译时分配的,并且是只读的。那部分记忆仍然存在"some string\0"

汇编中的CONST_DATA部分就像数据段 (DS),它包含在编译时本身初始化的全局和静态(只读)变量。它们在运行时不会更改,并保持分配给正在运行的程序。

于 2012-09-05T22:58:56.507 回答
3

答案非常好,但有几点他们遗漏或遗漏了。你的问题也有点模糊。

如果要清除 C 字符串,则用空字节覆盖它指向的内存空间。您只能free()通过调用堆分配器函数之一(例如malloc()calloc()realloc()等)来分配堆分配器分配的 C 字符串。

因此,如果您使用malloc()或其他堆分配函数之一分配字符串,然后将字符串复制到其中,则可以通过调用将其清除memset(),但您仍然必须调用free()以将该内存释放回堆.

例如:

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

另外,请注意,C 使用块作用域,您不必显式释放使用默认存储类 auto 声明的数组,因为当该块超出作用域时,它们会从堆栈框架中弹出。

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
}

最后,另一种分配方法是静态的。使用声明时:

char* str = "literal string";

字符串“literal string”的空间位于一个静态分配的段中,永远不应写入。在某些平台上,如果您尝试写入该内存段,则会出现段错误。您不应尝试清除静态分配的内存块,因为不能保证它们映射到的段是可写的。

于 2012-09-05T23:10:25.500 回答
2

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

无效自由(无效* ptr);

释放先前由 malloc()、calloc() 或 realloc() 分配的空间。如果 ptr 是空指针,该函数什么也不做。

您的字符串未分配任何这些函数。我想是这样的。

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;
}
于 2012-09-05T23:02:54.060 回答