当我编写以下代码时:
#include<stdio.h>
int* g(void){
int x = 10;
int *p = &x;
printf("%p,%p",p,&x);
return (p);
}
void main(){
int * p = g();
printf("\n%d",*p);
}
输出:
0060FED8,0060FED8
10
Process returned 3 (0x3) execution time : 0.031 s
地址和指向x
的指针都给出相同的值,但是当我返回地址&x
而不是指针p
时,代码不会输出的值x
了:
#include<stdio.h>
int* g(void){
int x = 10;
int *p = &x;
printf("%p,%p",p,&x);
return (&x);
}
void main(){
int * p = g();
printf("\n%d",*p);
}
警告:
warning: function returns address of local variable [-Wreturn-local-addr]
输出:
0060FED8,0060FED8
Process returned -1073741819 (0xC0000005) execution time : 8.332 s
有人可以告诉我我在做什么错吗?
答案 0 :(得分:1)
您一直在观察的是Undefined Behaviour
。 C编程语言中有一种叫做Storage Class的东西。函数int *g(void)
中的变量具有automatic storage class
。它们具有生命周期和功能范围。每当您退出函数后,分配给变量(x
和*p
)的位置都会被破坏。
因此,在其作用域之外(即,在函数(int *g(void)
之外)使用具有自动存储类的变量的地址是没有意义的,因为返回的指针将是悬空的指针。
如果要学习或使用函数范围之外的内存位置,可以使用heap
动态内存来分配空间。
您还可以使用全局变量,并从函数中返回该全局变量的内存地址。
#include <stdio.h>
#include <stdlib.h>
int x = 10;
int *g(void)
{
int *p = &x;
printf("%p,%p\r\n", p, &x);
return (&x);
}
int *heap(void)
{
int *p = malloc(sizeof(int));
*p = 100;
printf("%p\r\n", p);
return p;
}
int main(void)
{
int *p = g();
printf("%d\r\n", *p);
int *p1 = heap();
printf("%d\r\n", *p1);
return 0;
}
答案 1 :(得分:0)
由于x没有通过malloc或calloc在堆上分配内存,因此将其分配在所谓的堆栈上。堆栈主要用于局部变量。局部变量仅在声明的范围内存在。示波器是用穷人的话说的,介于两组匹配的括号之间。
int* g(void){
//x is allocated on the stack, since malloc wasn't used
int x = 10;
//p is pointing to x's spot in memory (on the stack)
int *p = &x;
//These addresses are the same, all is well so far
printf("%p,%p",p,&x);
//We return the memory location of x
//However, since this is the end of this scope (this function), any variables on the
//stack from this scope will be deleted, which means by the time we get back to main
//the variable "x" was deleted, so its spot in memory doesn't mean anything
return (&x);
}
答案 2 :(得分:0)
函数g将x声明为局部变量。这意味着x仅在声明它的地方可见/可用。将x的指针传递给main是没有用的,因为x对main()函数不可见。除非必要,否则总是使用指针返回。