我是C的新手,所以我知道指针是什么,但我对主题还不方便。
#include "stdio.h"
#include "stdint.h"
int *value(void) {
int i=3;
return &i;
}
void valueTwo(void) {
int x=35;
}
main() {
int *ip;
ip=value();
printf("*ip is %d\n", *ip);
valueTwo();
printf("*ip==%d\n",*ip);
}
以上代码打印 * ip是3 * ip是35
我不明白为什么* ip已从3变为35.据我所知,这意味着地址& i的值已从3更改为35.但是,我不明白35进入那个地址。谁能解释一下?谢谢!
答案 0 :(得分:3)
您正在返回导致根据C标准的未定义行为的局部变量i
的地址,问题是范围和局部变量的生命在函数vaule()
内,一旦控制返回对该变量的访问权限地址是无效的内存指令。
编辑:如果用-Wall编译代码,那么它也会给你警告:
$ gcc -Wall -pedantic x.c
x.c: In function ‘value’:
x.c:5:5: warning: function returns address of local variable
[enabled by default]
假设您的代码名称是x.c
您可以使用动态内存分配来纠正您的代码,如下所示:
int *value(void) {
int* i = malloc(sizeof(*i)); // it is dynamically allocated memory
*i = 3; // assigned 3 at allocated memory
return i; // safely return its address
}
现在,main中的*i
是安全的,因为动态分配内存的生命直到程序执行。
答案 1 :(得分:3)
您所看到的是未定义的行为。
int *value(void) {
int i=3;
return &i;
}
函数完成后,int i
超出范围。因此指针无效。
之后发生的一切都是未定义的。
答案 2 :(得分:2)
当在函数值中分配i时,它在堆栈上分配 - 也就是说,它是一个临时位置,仅在值运行时设置。当它退出时,你已经传回指针,但它在技术上不再有效。如果你很幸运,它仍然可以工作,因为没有任何东西可以覆盖那段记忆。
当你调用第二个函数时,它的分配方式与第一个函数完全相同,所以它恰好放在第一个变量" x"在" i"以前。您不能依赖于这种情况 - 另一个编译器可能会显示不同的行为。但这就是为什么它在现场写作35的原因" i"曾经是。
这是理解编译器如何工作的一个很好的练习,但不是在真实的程序中这样做。只需设置指针指向分配将在需要时保留的事物。
答案 3 :(得分:1)
此代码
int *value(void) {
int i=3;
return &i;
}
int i在堆栈中。返回地址,但是当函数结束时,堆栈的这部分可以被其他人自由使用。
即。不要像演示
那样做答案 4 :(得分:1)
返回本地变量的地址是一种灾难。你认为'i'局部变量存储在哪里?答案:存储'x'局部变量的完全相同的位置。