如何在C中取消声明(删除)变量?
就像我们使用宏一样:
#undef SOMEMACRO
我们是否也可以取消声明或删除C中的变量,以便我们可以节省大量内存?
我知道malloc()
和free()
,但我想完全删除这些变量,这样如果我使用printf("%d", a);
我应该得到错误
test.c:4:14: error: ‘a’ undeclared (first use in this function)
不,但是您可以创建小型的最小范围来实现这一点,因为当范围退出时,所有范围局部变量都会被销毁。 像这样的东西:
void foo() {
// some codes
// ...
{ // create an extra minimum scope where a is needed
int a;
}
// a doesn't exist here
}
这并不是对问题的直接回答,但它可能会带来一些命令和理解,为什么这个问题没有适当的答案,为什么在C中不可能“删除”变量。
点#1什么是变量?
变量是程序员为内存空间分配名称的一种方式。 这很重要,因为这意味着变量不必占用任何实际空间! 只要编译器有办法跟踪所讨论的内存,一个定义好的变量就可以用很多方式进行翻译,根本不占用任何空间。 考虑: const int i = 10;
编译器可以轻松地选择将i
所有实例替换为立即值。 在这种情况下, i
会占用0个数据存储器(取决于架构,它可能会增加代码大小)。 或者,编译器可以将该值存储在寄存器中,并且不会使用堆栈或堆空间。 “定义”主要存在于代码中的标签并没有必要在运行时定义。
点#2变量存储在哪里?
在第一点之后,你已经明白,这不是一个容易回答的问题,因为编译器可以在不破坏逻辑的情况下做任何事情,但一般来说,变量存储在堆栈中。 堆栈如何工作对于你的问题非常重要。 当一个函数被调用时,机器获取CPU指令指针的当前位置和当前堆栈指针,并将它们推入堆栈,将堆栈指针替换为堆栈上的下一个位置。 然后跳转到被调用函数的代码。
该函数知道它有多少变量以及它们需要多少空间,因此它会移动帧指针以捕获可能占用所有函数变量的帧,然后使用堆栈。 为了简化事情,函数从一开始就为所有变量捕获足够的空间,并且每个变量都有一个从函数堆栈帧*开始的明确偏移量。 变量也一个接一个地存储。 虽然你可以在这个动作之后操作帧指针,但是它会代价太高,而且毫无意义 - 运行代码只使用最后一个堆栈帧,并且如果需要可以占用所有剩余的堆栈(在线程启动时分配堆栈),因此“释放”变量没有什么好处。 从堆栈帧的中间释放一个变量需要进行碎片整理操作,这将非常昂贵并且无法恢复少量字节的内存。
第三点:让编译器完成工作
最后一个问题是一个简单的事实,即编译器在优化程序方面可能做得比您可能做得更好。 在需要的情况下,编译器可以检测变量作用域并覆盖无法同时访问的内存,以减少程序的内存消耗(-O3编译标志)。 无需您“释放”变量,因为编译器可以在您不知情的情况下执行此操作。
这是为了补充我之前所说的关于变量太小而不重要的事实以及没有机制来实现你所问的事实。
*支持动态大小数组的语言只有在计算数组的大小后才能改变堆栈框架以为该数组分配空间。
在C语言中,绝大多数编程语言中都无法做到这一点,当然,在我所知的所有编程语言中都是如此。
而且你不会节省“大量的记忆”。 如果你做了这样的事情,你将节省的内存量是微不足道的。 小。 不值得谈论。
有助于以这种方式清除变量的机制可能占用比您要清除的变量更多的内存。
调用能够回收单个变量代码的代码也会占用比变量本身更多的空间。
因此,如果有一个用于清除变量的神奇方法purge()
,不仅purge()
的实现将比您希望通过清除程序中的变量来回收的任何内存量都大,而且在int a; purge(a);
int a; purge(a);
调用purge()
会比占用更多的空间a
本身。
这是因为你所谈论的变量非常小。 printf("%d", a);
您提供的示例显示您正在考虑以某种方式回收单个int
变量占用的内存。 即使有办法做到这一点,你会节省4字节的顺序。 这些变量占用的内存总量非常小,因为它是程序员通过手工输入声明来声明多少个变量的直接函数。 在键盘上键入数年的操作,除了在声明大量占用大量内存的值的int
变量之前无意识地声明变量之外什么也不做。
上一篇: How to undeclare (delete) variable in C?
下一篇: Will a new Stack Frame be created on entering a block of statements?