sleepingawake86
sleepingawake86

Reputation: 41

Programming with global variables giving wrong results

I've been coding for a while in other languages and am pretty proficient, but now I am diving more deeply into C++ and have come across some weird problems that I never had in other languages. The most frustrating one, which a google search hasn't been able to answer, is with two different code orders.

The background is that I have an array of integers, and a pointer an element in the array. When I go to print the pointer one method prints correctly, and the other prints nonsense.

An example of the first code order is:

#include <iostream>

using namespace std;

void main(){
    int *pAry;
    int Ary[5]={2,5,2,6,8};

    pAry=&Ary[3];

    cout<<*pAry<<endl;

    system("pause");
}

and it works as expected. However this simple order wont work for the full project as I want other modules to access pAry, so I thought a global define should work, since it works in other languages. Here is the example:

#include <iostream>

using namespace std;
int *pAry;
void evaluate();

void main(){

    evaluate();
    cout<<*pAry<<endl;

    system("pause");
}

void evaluate(){
    int Ary[5]={2,5,2,6,8};
    pAry=&Ary[3];
}

When I use this second method the output is nonsense. Specifically 1241908....when the answer should be 6.

First I would like to know why my global method isn't working, and secondly I would like to know how to make it work. Thanks

Upvotes: 4

Views: 508

Answers (4)

JBentley
JBentley

Reputation: 6260

In the second example, Ary is local to the function evaluate. When evaluate returns, Ary goes out of scope, and accessing it's memory region results in undefined behaviour.

To avoid this, declare Ary in a scope where it will still be valid at the time you try to access it.

Upvotes: 8

Thomas Matthews
Thomas Matthews

Reputation: 57678

The problem is that you need to declare Ary with file scope.

int Ary[] = {1,2,3,4,5};

void print_ary(void); // The void parameter is a style thingy. :-)

int main(void)
{
  print_ary();
  return EXIT_SUCCESS;
}

void print_ary(void)
{
  for (unsigned int i = 0; i < (sizeof(Ary) / sizeof(Ary[0]); ++i)
  {
    std::cout << Ary[i] << std::endl;
  }
}

A better solution would be to pass a std::vector around to your functions rather than using a global variable.

Upvotes: 1

In the evaluate() function, you're aiming pAry at a variable (actually array element) local to that function. A pointer can only be dereferenced as long as the object to which it points still exists. Local objects cease to exist when they go out of scope; in this case, this means all elements of Ary cease to exist when evalute() ends, and thus pAry becomes a dangling pointer (it doesn't point anywhere valid).

Dereferncing a dangling pointer gives undefined behaviour; in your particular case, it outputs a garbage value, but it might just as well crash or (worst of all) appear to work fine until the program changes later.

To solve this issue, you can either make Ary global as well, or make it static:

void evaluate(){
    static int Ary[5]={2,5,2,6,8};
    pAry=&Ary[3];
}

A static local variable persists across function calls (it exists from first initialisation until program termination), so the pointer will remaing valid.

Upvotes: 3

Fred Larson
Fred Larson

Reputation: 62053

It's not working because your pAry is pointing into a local array, which is destroyed when you return from evaluate(). That's undefined behavior.

One possible fix is to make your local array static:

static int Ary[5]={2,5,2,6,8};

Upvotes: 4

Related Questions