user7620837
user7620837

Reputation:

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

I'm newbie in C language. 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?

Upvotes: 0

Views: 4121

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 753695

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).

If you access ptr when it contains a pointer that has gone out of scope, you get undefined behaviour.

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.

#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

Upvotes: 0

Michael
Michael

Reputation: 2414

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

Upvotes: 3

overseas
overseas

Reputation: 1731

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. When you leave func this pointer gets invalid.

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. The problem only comes into play later, when you try to dereference the variable after you left the function 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).

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().

With optimizations, the call to f2() will be optimized.

Still: This is undefined behavior and must not be done.

Upvotes: 3

Related Questions