如何清除传递给C中的函数的char *?

时间:2012-09-05 22:56:33

标签: c pointers

如何创建清除C字符串和/或释放已分配内存的功能?为什么以下代码不起作用?

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

5 个答案:

答案 0 :(得分:10)

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

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

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

答案 1 :(得分:4)

您分配的字符串位于 CONST_DATA 部分(无法修改),因此无法免费调用该字符串。

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

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

答案 2 :(得分:4)

您可能会发现查看C FAQ - malloc section

会很有帮助

正如其他人所说,你不能释放或修改字符串文字,因为它们通常放在内存的只读部分。但是,如果您希望清除并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;
}

答案 3 :(得分:2)

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

void free(void * 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;
}

答案 4 :(得分:2)

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

如果要清除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”的空间位于静态分配的段中,该段永远不应写入。在某些平台上,如果您尝试写入该内存段,则会出现段错误。您不应该尝试清除静态分配的内存块,因为不能保证它们映射到的段是可写的。

相关问题