2

I take an input for an array, then run a completely unrelated function. Somehow, the values of the array are different after this point. As far as I can tell, the first few values become zero (0).

Here is the opening segment of the main function:

int main()
{
    int i, j, k, n;
    Nod* root=NULL;    //Nod class user defined elsewhere
    cin>>n;
    int A[n];
    for(i=0; i<n; i++)
      {
          cin>>A[i];
          cout<<A[i]<<"\t";//TESTER
      }
    cout<<endl<<endl;
    Nod no[n];
    for(i=0; i<n; i++)
       no[i].nowhere(n);
    for(i=0; i<n; i++)
       cout<<A[i]<<"\t";//TESTER
    cout<<endl<<endl;

    ...//rest of main()
    ...
}

Here is the class Nod with the nowhere() function:

class Nod
{
    public: Nod* parent;
    Nod* child[];

    void nowhere(int n)
        {
            parent=NULL;
            for(int i=0; i<n; i++)
                child[i]=NULL;
        }
};

Here is a sample input and output:

Input:

5
4 -1 4 1 1

Output:

4    -1    4    1    1
0     0    4    1    1

As far as I can see, the nowhere() function should not affect the array A[] at all. Then, how are the values changing?

JeJo
  • 30,635
  • 6
  • 49
  • 88
PSinha
  • 39
  • 4
  • 2
    You need a [C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). You cannot learn by guessing and looking at code snippets on the interwebs. `Nod* child[];` is not doing what you imagine it's doing. It's not legal C++ at all. Nor is `cin>>n; int A[n];`. – n. m. could be an AI Aug 12 '18 at 10:22
  • If you are using g++ or clang, these flags are *mandatory*: `-std=c++17 -Wall -Werror -pedantic`. (You may have to use some lower number if your gcc is too old; see the documentation for your release). – n. m. could be an AI Aug 12 '18 at 10:26
  • also use of VLA is bad idea anyway – Алексей Неудачин Aug 12 '18 at 11:01

2 Answers2

4

Function nowhere causes undefined behavior by writing past the end of child[] array. The array has zero elements in your scenario, so accessing any index causes undefined behavior.

Since you are allocating Nods in an array, you should change child[] to std::vector<Nod*> child, and initialize it to an appropriate size dynamically as needed:

std::vector<Nod*> child;

void nowhere(int n) {
    parent = NULL;
    child = std::vector<Nod*>(n, NULL);
}

Note: Consider restructuring your code to not use "raw" pointers, or vectors of pointers. Switch to smart pointers, or use objects if possible.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Your problem:

You're getting zeros all over the first two cells of int A[n] as the result of undefined behavior caused by nowhere(int n) overwriting some of the contents of A[n]. The following loop does so:

for(int i=0; i<n; i++)
   child[i]=NULL;

The problem is that child is not being allocated before the iterated assignments of its cells to the value of NULL, and so you effectively write NULL (numerical value of 0) to an unexpected place in the memory. This is called an Overflow/Overrun. In your case the program overruns the address of where child resides, in a way that gets you zeroes all the way onto the content of int A[n].

The solution:

Use correct C++ to define child, like this:

std::vector<Nod*> child;

then, rewrite nowhere(int n) like this:

void nowhere(int n)
{
    parent=NULL;
    child.resize(n);
    for(int i=0; i<n; i++)
        child[i]=NULL;
}

BTW:

  1. You can forgo the entire looping in nowhere(int n) and this one liner does the resize() for you and fills the values like you wanted:

    child = std::vector<Nod*>(n, NULL);

  2. Nod* child[]; is quite likely not doing what you intended for it. The C++ syntax for C-style arrays of raw pointers would in this case be either:

    • Nod** child; if you're later allocating it dynamically like this child = new Nod*[n] (but don't forget to later free this memory with delete[] child)

    or

    • Nod* child[n]; if n is a constant expression -- which is not the case here anyways as you are receiving n as input.
Geezer
  • 5,600
  • 18
  • 31