Why can I still access a variable in the heap even after the function is over?

Asked

Viewed 63 times

-1

A while ago I learned about heap and stack, I was testing some codes when I came across a strange behavior in heap see;

#include <iostream>
using namespace std;

void Test1(int *i[]);
void Test2(int *i);

int main() 
{
    int *p[10];// declara um vetor ponterio para 10 inteiros
    int num_ = 10; //criar um interio com o nome num_ de valor 10 na heap

    p[0] = &num_; //passa o endereço de num_ para a primeira posiçao do vetor de ponteiros inteiros
    cout<< *p[0]<<endl; // mostra p[0] primeiro valor da primeira posiçao do vetor de ponteiros
    Test1(p);// chama a funçao Test1 q receber um vetor de ponteiros no paramentos
    cout<< *p[0]<<"**"<<endl; // o valor agr é 47, pq ?

//////////////////////////////////////////////////////////////////////////////////

    /*int *p_;
    int num__ = 10;
    p_ = &num__;
    cout<< *p_<<endl;
    soma_(p_);
    cout<< *p_<<endl;*/

    return 0;
}

void Test1(int *i[])
{
    int p = 47; //criar um inteiro na heap com valor 47
    i[0] = &p;/*passa o emdereço do interio "p" criado na heap para o vetor de interios*/
    /* no caso a variavel "p" foi criado na heap quando
     * essa funçao termina o "p" devia ser apagado assim p *i[0] agr nao devia aponta para luga nemhum,
     * mas quando sai da funçao Test1 o valor ainda esta acessivel no p[0] da main
     *  */
}

void Test2(int *i)
{
    int p = 47;
    i = &p;
}

Why can I still access the value 47 of the variable int p function Test1, if the value was for heap and when the function terminates the value p should be deleted? From what I understood about variables in heap, variables are deleted when function ends.

  • There’s nothing in the heap, then the question starts from something very wrong.

  • but in function Test1(int *p[]) there is a variable int p = 47 ,where it is if not in heap?

  • No Stack.......

  • ctz pq saw on some site that a variable within a function is always in the heap, only in the stack if it used the new operator to create

  • 1

    Never come back to this place that teaches wrong. Apparently it is exactly the opposite.

  • not sorry i that confusing the heap would be the biggest memory q uses new operdor to allocate ne

Show 1 more comment

1 answer

1


At no time does this code make use of the heap, then the confusion of what is happening there is general.

I imagine you don’t even realize you’re mixing C code with C++. It can, it works, but it’s not desirable if you know what you’re doing, okay, but usually people do it by accident.

It would be good to read a few things before to understand the basics of these concepts. Search more on the site because there are other questions asked that will help you understand after learning the basics.

This is one of the famous codes that work, but they’re wrong. The good part of doing it in C or C++ is that it lasts a little bit, soon it will burst and give problem, it will be a little too late in some cases, but it will be so chaotic that one will have to tidy up. In fact almost everyone gives up these languages after passing this grip and opts for languages that errors do not cause as much trouble. Some languages work even wrong things for almost all the time and this is enough for many people. Here I am giving you the tip to avoid this path, but I know that most ignore and still prefer to just see working.

Fiat 147 todo detonado andando pelas ruas

In case all allocations are in the stack. Local variables and parameters that are still local variables.

int *p[10];// declara um vetor ponterio para 10 inteiros

This is wrong. You are declaring a 10 position vector with pointers for integers (these pointers should point to integers)

cout<< *p[0]<<endl; // mostra p[0] primeiro valor da primeira posiçao do vetor de ponteiros

This is confusing. It is showing the value pointed by the first vector position p.

cout<< *p[0]<<"**"<<endl; // o valor agr é 47, pq ?

Because whenever something passes by reference, and a vector is always a reference (a pointer), is not passing the object, is not copying that content, is copying the pointer that points to the real object, so whatever you do in the other function will reflect on the original object because both here and there is pointing to the same object, then it is obvious that a change in some element of it no matter where the change happened will be made in the pointed object, any place that accesses that object will have the same data. Therefore we say that it is a mutable object, different from an isolated integer for example that is immutable and by value and the object is always copied becoming another object in each different use.

 i[0] = &p;/*passa o emdereço do interio "p" criado na heap para o vetor de interios*/

Here is the error I mentioned. It is storing in the vector a pointer to the value previously declared in stack. As you must have learned, at the end of the execution of the function the variables of stack no longer exist. But it is the variable that ceases to exist, not the object, just the lifespan of them, but n]ao there is a destruction. Of course, if the variable no longer points to it it does not consider it safe to continue accessing it, at any time it may cease to exist since it is no longer necessary. There it can be replaced by another value, another object can be placed in its place. Actually in the first function call that has local variables that assign value to them will overwrite right up there where that object was (it depends a little on some factors, it’s not so simple because it depends on the implementation).

Since you didn’t call any other function that damaged your object is working, but that’s a coincidence, don’t count on it.

If you want the object to survive the end of the function one of the forms is to put it in the heap, and then the management of its life time is determined by you. In archaic C++ is allocated with new and removes with delete with the era with malloc() and free() in C. But today in C++ it is done very differently, more safely and automatically. These operators have become virtually implementation detail in almost every modern code scenario.

All of this is not required in C or C++, but this is how all implementations work.

Actually this code has several errors and does not even compile so all this is theoretical. I redid the code demonstrating what you are talking about:

#include <iostream>
using namespace std;

void Test2(int *i) {
    int p = 147;
    i = &p;
}

int main() {
    int *p[10];
    int num = 10;
    p[0] = &num;
    cout << *p[0] << endl;
    Test2(p[0]);
    cout << *p[0] << endl;
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • Excellent answer, but then despite working when I call the "Cout<< *[0] ; show the 47 but can da mer...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.