10

所以我正在阅读一个类的一些代码,我对如何在 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* 释放任何内存,因为没有发生 malloc,但我不明白为什么这段代码不会泄漏任何内存......如果你正在增加一个字符串的指针并且因此将指针移动到下一个内存块(1字节)然后你不会失去初始参考和你增加的所有参考点吗?如果没有参考点,该内存将如何被回收,除非在此类操作发生之前由编译器保存。我将不胜感激有关如何回收的一些见解!

4

7 回答 7

13

The task of deallocating memory is imposed on the owner of that memory. Just because you have a pointer to some memory region does not mean that you own that memory and, therefore, does not mean that you are responsible for deallocating it.

String literal "hello world" is an object with static storage duration. It is stored in static memory. Static memory is always owned by the runtime environment. The runtime environment is aware of data stored in static memory. The runtime environment knows when that data has to be deallocated (which is easy, since static memory is basically "never" deallocated - it exists as long as your program runs).

So, again, you with your pointer p do not really own any memory in static region. You just happen to refer to that memory with your p . It is not your business to worry about deallocation of that memory. It will be properly deallocated when the time comes (i.e. when the program ends) and it will be done properly without any help from you and your pointer p. You can change your p as much as you want, you can make it point to a completely different memory location, or you can discard it without any reservations. Speaking informally, nobody cares about your p.

The only memory you can possibly own in a C program is memory you personally allocated with malloc (or other dynamic memory allocation functions). So, you have to remember to eventually call free for the memory that you allocated yourself (and you have to make sure you know the original value returned by malloc to pass to that free). All other kinds of memory (like static or automatic) are never owned by you, meaning that freeing it is not your business and preserving the original pointer values is completely unnecessary.

于 2013-11-05T00:46:30.320 回答
12

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

于 2013-11-05T00:26:10.507 回答
3

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

于 2013-11-05T00:29:02.990 回答
2

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

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

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

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

于 2013-11-05T00:40:45.373 回答
0

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

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

为什么我要解释这个事实是,每当您调用 new 或 malloc(或 calloc)时,释放您不想再使用的内存是您的责任。

于 2013-11-05T00:36:35.353 回答
0

简而言之:因为程序本身很短。你可以在那里做任何malloc你想做的事情,并且实际上不会发生泄漏,因为所有内存都会在进程结束后立即交还给操作系统。在您的示例中,泄漏不是问题。反正,

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

于 2013-11-05T00:29:44.113 回答
0

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

递增指针不会改变指针曾经指向的字节。“H”,还在。但是程序现在认为字符串以“e”开头。(它知道字符串的结尾在哪里,因为按照惯例,C 中的字符串以null.

没有检查指针是否指向您认为它应该指向的位置,或者根本没有任何有效区域。p=0程_取消分配用于字符串的内存。

如果您将指针更改为指向内存中的“错误”位置,就会发生有趣(坏)的事情——例如页面错误、堆栈溢出和核心转储。

于 2013-11-05T00:55:06.307 回答