简体   繁体   English

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

[英]Assign the address of local variable to global pointer in C?

I'm newbie in C language. 我是C语言的新手。 If I assign the address of local variable to global pointer, What happens? 如果我将局部变量的地址分配给全局指针,会发生什么? Like, 喜欢,

#include <stdio.h>

void func();
int *ptr;

int main()
{
    func();
}

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

Is it correct way to assign the address of local variable to global pointer? 将局部变量的地址分配给全局指针是否正确?

It just does what you do, there is nothing wrong about it, except that it probably is not what you want. 它只是完成您的操作,没有错,只是它可能不是您想要的。

So it just assigns the address of i to ptr at the point you assign it. 因此,它只是在分配点时将i的地址分配给ptr When you leave func this pointer gets invalid. 当您离开func此指针无效。

Note This behaviour is fully defined: The address of i at the place you assign it to the global variable is defined, and so you can assign it. 注意此行为已完全定义:将i分配给全局变量的位置的地址已定义,因此您可以对其进行分配。 The problem only comes into play later, when you try to dereference the variable after you left the function func . 只有离开函数func 之后尝试取消引用变量时,问题才会出现。 As long as you only use the global variable in func there is no problem in this (except that a global variable is really meaningless). 只要您仅在func使用全局变量,就不会有任何问题(除非全局变量实际上是没有意义的)。

At this point, this variable doesn't exist anymore. 在这一点上,此变量不再存在。 And it is very likely that you either get a segfault or at least you get some strange numbers (because you have overwritten the old stack frame with some other values) in this case. 在这种情况下,很可能您遇到段错误或至少得到一些奇怪的数字(因为您已经用其他一些值覆盖了旧的堆栈框架)。


Just as a side note: What I mean with this stack frame thing . 恰如其分:我对这个堆栈框架的意思是什么 You can try this code on most compilers (without optimizations!) 您可以在大多数编译器上尝试使用此代码(无需优化!)

#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);
}

Without optimizations, this will most probably print 没有优化,这很可能会打印

0
1

Because the variable i will have the same address when calling f1 and f2 from main() . 因为从main()调用f1f2时,变量i将具有相同的地址。

With optimizations, the call to f2() will be optimized. 通过优化,将优化对f2()的调用。

Still: This is undefined behavior and must not be done. 仍然:这是未定义的行为,绝不能执行。

Your syntax is correct, but the local variable ceases to exist because it belongs within the scope of the function call's code block. 您的语法是正确的,但是局部变量不再存在,因为它属于函数调用的代码块的范围。 To resolve this, one option is to make the local variable static: 要解决此问题,一种选择是使局部变量静态:

#include <stdio.h>

void func();
int *ptr;

int main()
{
    func();
}

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

Another option would be to allocate new memory within the function call, setting the global pointer to the address of that newly allocated memory: 另一种选择是在函数调用内分配新的内存,将全局指针设置为该新分配的内存的地址:

#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;
}

What you've got is syntactically correct, and the code as written is semantically valid (but since ptr is never used, it is a bit pointless). 您所获得的内容在语法上是正确的,并且所编写的代码在语义上是有效的(但是由于从未使用过ptr ,因此它毫无意义)。

If you access ptr when it contains a pointer that has gone out of scope, you get undefined behaviour. 如果在ptr包含超出范围的指针时访问ptr ,则会得到未定义的行为。

However, consider a slightly larger code fragment. 但是,请考虑稍大的代码片段。 Here, the code that sets ptr calls a function that uses ptr , and the variable that ptr points to is still defined, so there is no problem using the pointer. 在这里,设置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;
}

This is legitimate code — though using global variables is something you should generally avoid and perfectly well could avoid. 这是合法的代码-尽管通常应该避免使用全局变量,但完全可以避免。

Sample output: 样本输出:

func: A 0
ptr = 0x7fff55be74ac; *ptr = 0
func: B 42
main: A 20
ptr = 0x7fff55be74cc; *ptr = 20
main: B 42

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM