将局部变量的地址分配给C中的全局指针?

时间:2017-03-04 16:30:24

标签: c pointers

我是C语言的新手。如果我将局部变量的地址分配给全局指针,会发生什么?像,

#include <stdio.h>

void func();
int *ptr;

int main()
{
    func();
}

void func()
{
    int i = 0;
    ptr = &i;
} 

将局部变量的地址分配给全局指针是否正确?

3 个答案:

答案 0 :(得分:2)

它只是做你做的事情,没有什么不妥,除了它可能不是你想要的。

因此,它只会在您指定的位置将i的地址指定给ptr。离开func时,此指针无效。

注意此行为已完全定义:已定义将i分配给全局变量的位置的地址,因此您可以对其进行分配。该问题仅在稍后发挥作用,当您尝试在之后取消引用变量时,您离开了函数func。只要你在func中使用全局变量就没有问题(除了全局变量真的没有意义)。

此时,此变量不再存在。在这种情况下,你很可能得到一个段错误或至少得到一些奇怪的数字(因为你用其他一些值覆盖了旧的堆栈帧)。

正如旁注:我对这个堆栈框架事物的意思。您可以在大多数编译器上尝试此代码(无需优化!)

#include <stdio.h>
int *ptr;

void f1() {
  int i = 0;
  ptr = &i;
}
void f2() {
  int i = 1;
}

int main() {
  f1();
  printf("%d\n", *ptr);
  f2();
  printf("%d\n", *ptr);
}

如果没有优化,很可能会打印

0
1

因为从i调用f1f2时,变量main()将具有相同的地址。

通过优化,可以优化对f2()的调用。

仍然:这是未定义的行为,不得这样做。

答案 1 :(得分:2)

您的语法是正确的,但局部变量不再存在,因为它属于函数调用代码块的范围。要解决此问题,一个选项是将局部变量设为静态:

#include <stdio.h>

void func();
int *ptr;

int main()
{
    func();
}

void func()
{
    static 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;
}

答案 2 :(得分:0)

你得到的是语法正确,所写的代码在语义上是有效的(但由于永远不会使用<!-- Link to Registration Screen --> <TextView android:id="@+id/link_to_register" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="40dip" android:layout_marginBottom="40dip" android:text="New to Twitter? Register here" android:gravity="center" android:textSize="20dip" android:textColor="#0b84aa"/> ,所以它有点无意义。)

如果在包含超出范围的指针时访问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;
}