1

I am learning classes and OOP, so I was doing some practice programs, when I came across the weirdest bug ever while programming.

So, I have the following files, beginning by my class "pessoa", located in pessoa.h:

#pragma once
#include <string>
#include <iostream>

using namespace std;

class pessoa {
public:
//constructor (nome do aluno, data de nascimento)
pessoa(string newname="asffaf", unsigned int newdate=1996): name(newname), DataN(newdate){};
void SetName(string a); //set name
void SetBornDate(unsigned int ); //nascimento
string GetName(); //get name
unsigned int GetBornDate();
virtual void Print(){}; // print

private:
string name; //nome
unsigned int DataN; //data de nascimento
};

Whose functions are defined in pessoa.cpp

#include "pessoa.h"

string pessoa::GetName ()
{
    return name;
}

void pessoa::SetName(string a)
{
    name = a;
}

unsigned int pessoa::GetBornDate()
{
    return DataN;
}

void pessoa::SetBornDate(unsigned int n)
{
    DataN=n;
}

A function, DoArray, declared in DoArray.h, and defined in the file DoArray.cpp:

    pessoa** DoArray(int n)
{
    pessoa* p= new pessoa[n];
    pessoa** pointer= &p;
    return pointer;
}

And the main file:

#include <string>
#include <iostream>
#include "pessoa.h"
#include "DoArray.h"
#include <cstdio>

using namespace std;

int main()
{
//pessoa P[10];
//cout << P[5].GetBornDate();
pessoa** a=DoArray(5);
cerr << endl << a[0][3].GetBornDate() << endl;
cerr << endl << a[0][3].GetName() << endl;


    return 0;
}

The weird find is, if I comment one of the methods above, "GetBornDate" or GetName, and run, the non-commented method will run fine and as supposed. However, if both are not commented, then the first will run and the program will crash before the 2nd method.

Sorry for the long post.

Joshua Dannemann
  • 2,003
  • 1
  • 14
  • 34
Kelthar
  • 124
  • 9

1 Answers1

5

Let's look into this function:

int *get()
{
    int i = 0;
    return &i;
}

what is the problem with it? It is returning pointer to a local variable, which does not exist anymore when function get() terminates ie it returns dangling pointer. Now your code:

 pessoa** DoArray(int n)
 {
     pessoa* p= new pessoa[n];
     return &p;
 }

do you see the problem?

To clarify even more:

 typedef pessoa * pessoa_ptr;
 pessoa_ptr* DoArray(int n)
 {
     pessoa_ptr p= whatever;
     return &p;
 }

you need to understand that whatever you assign to p does not change lifetime of p itself. Pointer is the same variable as others.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • But I think that when you dynamically declare a variable (as with the "new" command), that variable isn't deleted after I close the program (the opposite if I did it statically). Anyway, if the my local variable was deleted, then I would be able to run none of the method calls! One of them works (one or another, just not both), so my variable wasn't deleted. Am I wrong? – Kelthar Oct 28 '15 at 18:25
  • @allg18 Your "pessoa" isn't deleted, but the pointer p itself is. As you pass back the address of `p` you have a dangling reference. – dascandy Oct 28 '15 at 18:26
  • @dascandy Hmm, but then why does it work if I comment `cerr << endl << a[0][3].GetBornDate() << endl;` for example? If I do this it the "cerr with the GetName()" will run with no problems, printing the name it is supposed to print – Kelthar Oct 28 '15 at 18:30
  • @allg18 I added another clarification to the answer, just think about it. The fact that something "works" does not prove anything. – Slava Oct 28 '15 at 18:33
  • 1
    @allg18 it does not matter what side effects you have, you program has UB, it can do whatever. – Slava Oct 28 '15 at 18:35
  • @Slava So, if I get it right, what is happening is that when I do the first method call, the pointer is "still alive", but it is deleted before the 2nd method call? – Kelthar Oct 28 '15 at 18:39
  • @allg18 no it is not alive, but that does not mean it will immedeatly crash. you should not care what happens there, you change compiler, compiler version, compilation flags, code in your program and it may work differently. You are wasting time trying to understand why it has specific symptoms. – Slava Oct 28 '15 at 18:45
  • @allg18 read answer to this question http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope it should explain why that your program not crashing immediately does not mean anything. – Slava Oct 28 '15 at 18:50