如何在C中取消分配char *

时间:2013-11-05 00:22:25

标签: c string memory

所以我正在阅读一些类的代码,我对如何在C中释放变量感到困惑。

给出的代码是

#include<stdio.h>
main () {
    int n=0; 
    char *p = "hello world";
    while (*p!= 0)  {   // *p != '\0';
        putc(*p, stdout);
        p++;
    }
    printf("\np = %d", *p);
    printf("\np = %d\n", p);
}

所以我得到你不需要为char *释放任何内存,因为没有mallocs正在发生但我不明白为什么这段代码不会泄漏任何内存...如果你正在增加一个指针一个字符串,从而移动指向下一个内存块(1byte)的指针,那么你是不是丢失了初始引用和你增加的所有引用点?如果没有参考点,将如何回收此内存,除非在此类操作发生之前编译器保存了一个内存。我很感激有关如何回收它的一些见解!

7 个答案:

答案 0 :(得分:13)

解除内存释放的任务强加于该内存的所有者。仅仅因为你有一个指向某个内存区域的指针并不意味着你拥有那个内存,因此,并不意味着你有责任解除分配它。

字符串文字"hello world"是具有静态存储持续时间的对象。它存储在静态存储器中。静态内存始终归运行时环境所有。运行时环境知道存储在静态存储器中的数据。运行时环境知道何时必须释放该数据(这很容易,因为静态内存基本上“从未”被释放 - 只要程序运行就存在)。

所以,再次,你的指针p并没有真正拥有静态区域的任何内存。您恰好使用p 引用到该内存。担心释放内存不是您的事。当时间到来时(即程序结束时)它将被正确释放,并且在没有你和指针p的任何帮助的情况下正确地完成它。您可以根据需要更改p,可以指向完全不同的内存位置,也可以不加任何保留地丢弃它。非正式地说,没有人关心你的p

C程序中唯一可能拥有的内存是您个人使用malloc(或其他动态内存分配函数)分配的内存。因此,您必须记住最终为您自己分配的内存调用free(并且您必须确保知道malloc返回的原始值以传递给free) 。所有其他类型的内存(如静态自动)永远不归您所有,这意味着释放它不是您的业务,保留原始指针值是完全没必要的。< / p>

答案 1 :(得分:11)

您没有泄漏任何内存,因为您没有动态分配任何内存。内存泄漏来自于不释放动态分配的内存。本地分配的内存(如char *p)或静态分配的内存(如"hello world"最初指向的字符串p)无法导致泄漏。

答案 2 :(得分:2)

您没有动态分配任何新内存,因此您无需释放它。

答案 3 :(得分:2)

字符串文字"hello world"是一个对象,它是程序本身的一部分。当评估"hello world"表达式时,程序基本上获得指向其自身的指针。程序运行时无法释放该内存;这相当于在程序中制造一个“漏洞”。内存与程序本身具有相同的生命周期。

在C语言中,程序员不需要管理与程序具有相同生命周期的内存:这是由启动程序的环境进行外部管理(或视情况而定管理不当),并处理程序终止后的后果。

当然,内存仍然需要管理;只是责任不在于C程序。 (至少,不是在提供C语言的托管实现的环境中。某些嵌入式系统的规则可能不同!)

在嵌入的程序中,字符串文字(以及程序的其余部分)实际上可以存在于ROM中。所以可能真的没有什么可以清理的。指针是一个地址,指的是芯片上的某个永久位置(或几个芯片)。

答案 4 :(得分:0)

简而言之:因为程序本身很短。您可以在那里执行任何malloc,并且实际上不会发生泄漏,因为一旦进程结束,所有内存都将被传回操作系统。在您的示例中,泄漏不会成为问题。无论如何,

在你的情况下,没有发生泄漏,因为变量p指向一个文字字符串,它位于内存的数据段中(即它是一个常量,写在可执行文件中) 。这种内存不能被解除分配,因为它的空间是固定的。 实际上,这不是一个问题,这是错误的,因为一个非常大的可执行文件,其中有很多大常量,可能会有非凡的内存占用,但无论如何这不称为泄漏,因为内存使用可能是大,但它不会随着时间的推移而增加,这是内存泄漏的主要原因(因此名称​​ leak )。

答案 5 :(得分:0)

当您在本地声明变量时,编译器知道每个变量需要多少空间,并且在运行程序时,每个局部变量(以及每个函数调用)都被置于堆栈中。在return语句之后(或者如果是void函数的}括号),每个局部变量都从堆栈中弹出,因此您不必释放它。

当您调用new运算符(或纯C中的malloc)时,编译器不知道数据的大小,因此内存在堆上运行时被分配。

为什么我要解释这个事实,无论何时你打电话给new或malloc(或calloc),你都有责任释放你不想再使用的记忆。

答案 6 :(得分:0)

除了其他答案之外,在C中递增指针不会创建或丢失&#34;引用&#34;,也不会导致指针指向的内存的任何复制或其他更改。在这种情况下,指针只是一个恰好指向静态分配的内存区域的数字。

递增指针不会改变指针指向的字节。 &#34; H&#34;仍然存在。但是程序现在认为字符串以&#34; e&#34;开头。 (它知道字符串结尾的位置,因为C末尾的约定字符串带有null

没有检查指针指向您认为它应该是什么,或任何有效区域。程序本身可能会丢失内存区域(例如,如果设置p=0),或者将p增加到字符串末尾之外,但编译器不会跟踪此(或阻止它) ),它不会取消分配用于字符串的内存。

如果您将指针更改为指向&#34;错误&#34;在内存中的位置,有趣(坏)的事情将发生 - 例如页面错误,堆栈溢出和核心转储。