将局部变量的地址分配给C中的全局指针?
我是C语言的新手。如果我将局部变量的地址分配给全局指针,会发生什么?像将局部变量的地址分配给C中的全局指针?,c,pointers,C,Pointers,我是C语言的新手。如果我将局部变量的地址分配给全局指针,会发生什么?像 #include <stdio.h> void func(); int *ptr; int main() { func(); } void func() { int i = 0; ptr = &i; } #包括 void func(); int*ptr; int main() { func(); } void func() { int i=0; ptr=&i; } 将
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
int i = 0;
ptr = &i;
}
#包括
void func();
int*ptr;
int main()
{
func();
}
void func()
{
int i=0;
ptr=&i;
}
将局部变量的地址分配给全局指针是正确的方法吗?它只是执行您所做的操作,没有任何错误,只是它可能不是您想要的 因此,它只是将
i
的地址分配给ptr
的分配点。离开func
时,此指针无效
注意此行为已完全定义:已定义分配给全局变量的位置处的i
的地址,因此您可以分配它。当您离开函数func
后尝试取消对变量的引用时,此问题才会出现。只要只在func
中使用全局变量,这就没有问题(除了全局变量实际上没有意义)
此时,该变量不再存在。在这种情况下,很可能会出现segfault,或者至少会出现一些奇怪的数字(因为您已经用一些其他值覆盖了旧堆栈帧)
作为旁注:我指的是堆叠框架。您可以在大多数编译器上尝试此代码(无需优化!) 因为从
main()
调用f1
和f2
时,变量i
将具有相同的地址
通过优化,对f2()
的调用将得到优化
仍然:这是未定义的行为,不能执行。它只是做你所做的事情,没有什么错,只是它可能不是你想要的 因此,它只是将
i
的地址分配给ptr
的分配点。离开func
时,此指针无效
注意此行为已完全定义:已定义分配给全局变量的位置处的i
的地址,因此您可以分配它。当您离开函数func
后尝试取消对变量的引用时,此问题才会出现。只要只在func
中使用全局变量,这就没有问题(除了全局变量实际上没有意义)
此时,该变量不再存在。在这种情况下,很可能会出现segfault,或者至少会出现一些奇怪的数字(因为您已经用一些其他值覆盖了旧堆栈帧)
作为旁注:我指的是堆叠框架。您可以在大多数编译器上尝试此代码(无需优化!) 因为从
main()
调用f1
和f2
时,变量i
将具有相同的地址
通过优化,对f2()
的调用将得到优化
仍然:这是未定义的行为,不能执行。您的语法正确,但局部变量不再存在,因为它属于函数调用的代码块的范围。要解决此问题,一个选项是将局部变量设为静态:
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
static int i = 0;
ptr = &i;
}
#包括
void func();
int*ptr;
int main()
{
func();
}
void func()
{
静态int i=0;
ptr=&i;
}
另一个选项是在函数调用中分配新内存,将全局指针设置为新分配内存的地址:
#include <stdio.h>
void func();
int *ptr = NULL;
int main()
{
func();
}
void func()
{
if(ptr != NULL)
free(ptr);
int *i = (int *)malloc(sizeof(int));
ptr = i;
}
#包括
void func();
int*ptr=NULL;
int main()
{
func();
}
void func()
{
如果(ptr!=NULL)
免费(ptr);
int*i=(int*)malloc(sizeof(int));
ptr=i;
}
语法正确,但局部变量不再存在,因为它属于函数调用的代码块范围。要解决此问题,一个选项是将局部变量设为静态:
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
static int i = 0;
ptr = &i;
}
#包括
void func();
int*ptr;
int main()
{
func();
}
void func()
{
静态int i=0;
ptr=&i;
}
另一个选项是在函数调用中分配新内存,将全局指针设置为新分配内存的地址:
#include <stdio.h>
void func();
int *ptr = NULL;
int main()
{
func();
}
void func()
{
if(ptr != NULL)
free(ptr);
int *i = (int *)malloc(sizeof(int));
ptr = i;
}
#包括
void func();
int*ptr=NULL;
int main()
{
func();
}
void func()
{
如果(ptr!=NULL)
免费(ptr);
int*i=(int*)malloc(sizeof(int));
ptr=i;
}
您得到的是语法正确的,并且编写的代码在语义上是有效的(但是由于从来没有使用过ptr
,所以它有点毫无意义)
如果您访问ptr
,当它包含超出范围的指针时,您会得到未定义的行为
但是,请考虑一个稍微大一些的代码片段。这里,设置
ptr
的代码调用使用ptr
的函数,并且ptr
指向的变量仍然是定义的,因此使用指针没有问题
#include <stdio.h>
void func(void);
void use_pointer(void);
int *ptr;
int main(void)
{
func(); // NB: argument not allowed with prototype!
int i = 20;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void func(void)
{
int i = 0;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void use_pointer(void)
{
printf("ptr = %p; *ptr = %d\n", (void *)ptr, *ptr);
*ptr = 42;
}
您得到的是语法正确的,并且编写的代码在语义上是有效的(但是因为从来没有使用过ptr
,所以它有点毫无意义)
如果您访问ptr
,当它包含超出范围的指针时,您会得到未定义的行为
但是,请考虑一个稍微大一些的代码片段。这里,设置
ptr
的代码调用使用ptr
的函数,并且ptr
指向的变量仍然是定义的,因此使用指针没有问题
#include <stdio.h>
void func(void);
void use_pointer(void);
int *ptr;
int main(void)
{
func(); // NB: argument not allowed with prototype!
int i = 20;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void func(void)
{
int i = 0;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void use_pointer(void)
{
printf("ptr = %p; *ptr = %d\n", (void *)ptr, *ptr);
*ptr = 42;
}
调用表达式的未定义行为与被调用函数的类型不匹配。您的赋值是正确的;但是,离开func
后,变量i
不再存在,从此以后您就有了未定义的行为。查找“悬空指针”未定义的行为,查找与被调用函数类型不匹配的调用表达式。