C新手,请教下局部变量的回收问题。
今天写个链表,结果我发现下面 test_add 方法里声明的局部变量好像并没有被回收,用的是同一个内存地址的空间,所以,第二次调用函数,重新声明的变量依然用的是上一次的赋值。
我想问下这是什么原因?按照我自己理解局部变量应该会用新地址,但实际不是,是因为C标准这么规定的吗?
#include <stdio.h>
void test_add(int n);
typedef struct node_s node_t;
struct node_s {
int num;
node_t *next;
};
static node_t node_queue;
int main(int argc, char *argv[]) {
node_queue.next = &node_queue;
test_add(1);
test_add(2);
test_add(3);
for (node_t *temp = node_queue.next; temp != &node_queue; temp = temp->next) {
printf("%dn", temp->num);
}
return 0;
}
void test_add(int n) {
node_t new_node;
// 本来以为重新调用方法,new_node 应该是新分配的空间才对,但其实用的旧的
printf("声明:%d\n", new_node.num);
printf("地址:%p\n", &new_node);
new_node.num = n;
// 插入队列, 因为 new_node 的地址没变,导致 queue 里的队列不正确
new_node.next = node_queue.next;
node_queue.next = &new_node;
}
test_add 里的输出结果:
声明:-335181312
地址:0x7ffeec0589a8
声明:1
地址:0x7ffeec0589a8
声明:2
地址:0x7ffeec0589a8
gcc 环境是:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
局部变量的地址是在堆栈上,其实并没有没有回不回收的概念,你三次test_add都是在同一层堆栈调用的,自然地址都是一样的
你要是像评论里说的那样递归去调用(或者其他方法),让test_add在不在同一层堆栈,申请到的地址就不一样了
想要多了解原理可以学学汇编相关的知识
而且我看了看你的需求,你add一个新节点不应该使用局部变量(局部函数退出后,这块内存随时可能会被别处使用,就会出问题),而是应该手动申请一块新内存去给新节点使用