0

Assume we have two fragments of C++ code:

1:

void fun1()
{
    if(1)
        int a=5;
}

2:

void fun2()
{
    if(1)
        {
            int *b = new int;
            b = 5;
            delete b;
        }
}

Are they equivalent? Is the memory allocated for the a variable freed after program leaves the if block? If not, when it is freed?

Andrew
  • 5,212
  • 1
  • 22
  • 40
mmichal10
  • 322
  • 2
  • 13
  • 5
    You probably want `*b = 5` instead of `b = 5`. And no these are not equivalent because the first one is allocated on the stack while the second one allocates on the heap. – Holt May 11 '16 at 14:02
  • 1
    As well as what Holt says, note that stack allocation is far faster than heap allocation. – Robinson May 11 '16 at 14:03
  • 2
    Well, the first one may not be allocated anywhere at all or (if it is) it's just a fixed memory location in your **data segment** (not on stack, btw) but it's really a compiler thing, it will do what it prefers- assuming there aren't special storage modifiers (I also assume missing * is just a typo...) – Adriano Repetti May 11 '16 at 14:03
  • I imagine you could use a sizeof() function to determine this yourself. That's the first step I would take. And @Holt is correct, you your b = 5 is not doing what you are expecting it to. – Retro Gamer May 11 '16 at 14:04
  • The second one as it is would even be a segfault, since it would try to delete memory at address 5 (where it wasn't allocated). – Matthias247 May 11 '16 at 14:04
  • 1
    the biggest difference is that `1` is idiomatic, and `2` is an anti-pattern. use value semantics wherever possible. use smart-pointers for the rest. [no naked new](http://stackoverflow.com/questions/20848411/about-the-usage-of-new-and-delete-and-stroustrups-advice) – sp2danny May 11 '16 at 14:18
  • @AdrianoRepetti: Data segment? Unlikely, since it's a function-local variable. Each call has its own copy of `a`. Now since `fun1` isn't recursive, this means it could be in thread-local memory, but it can't be in a (shared) data segment. – MSalters May 11 '16 at 14:25
  • @MSalters in this example it won't probably be anywhere but...where to allocate it depends on compiler (AFAIK). It (compiler) may always put it in the stack (and load with offset) or decide it's better to use a shared memory location (why not? I'm thinking about read-only brace initialized struct) AFAIK it has freedom to do what is better for its optimization scheme – Adriano Repetti May 11 '16 at 14:41
  • @AdrianoRepetti: The reason why it can't be in a shared location is because two threads must be able to call `fun1` and have two different values of `a`. A shared location can hold only a single value. (Ignoring for a moment that `a` can be optimized away in this trivial example). – MSalters May 11 '16 at 14:54
  • @MSalters you're right for general case, I was just thinking about a read-only case but it's even more corner case than this example – Adriano Repetti May 11 '16 at 15:48

4 Answers4

0

They are not equivalent. In fun1 a would either be a register or possibly a location on the stack depending on compiler optimizations. Either way, it goes out of scope after the if "block." In fun2 your storage would be on the heap. In general and for small and short-lived objects, fun1 will far out-perform fun2.

mark
  • 5,269
  • 2
  • 21
  • 34
0

When the functions complete, both 'a' and 'b' will be freed from memory. 'a' will be deallocated because it left scope, 'b' will be deallocated because you explicitly called delete.

They are not equivalent in terms of memory. In fun1() you allocate one int to your stack. In fun2() you allocate one int pointer on your stack and one int in your heap. This means fun2() is slightly slower and uses more memory.

Ryan
  • 314
  • 1
  • 10
  • C++ does not have the concept of stack or heap. These are implementation details of the compiler.Variables are defined in terms of storage duration automatic/static/dynamic. – Martin York May 11 '16 at 15:31
0

Assuming you have a typo in the second function.

Are they equivalent?

First function will do virtually nothing meanwhile second function will invoke operator new which might be overloaded and operator delete which also might be overloaded. This will allocate dynamic memory and free it eventually. And what is more important, second function can throw an exception.

Is the memory allocated for the a variable freed after program leaves the if block?

In the first function memory will be freed after leaving the scope if it were allocated. In the second example memory will be freed after execution of delete operator, but keep in mind that you have a pointer as a local variable which will perform like in first case.

Teivaz
  • 5,462
  • 4
  • 37
  • 75
0

The { ... } is known as a compound statement. If the braces are omitted in an if statement the enclosed statement is still a compound statement. Compound statements have block scope. This means variables with automatic storage are destroyed at the end of block scope.

void fun1()
{
    if(1)
        int a=5; // a destroyed at semi-colon
}

void fun2()
{
    if(1)
        {
            int *b = new int;
            b = 5;
            delete b;
        } // b destroyed at brace
}

The life time of the memory allocated with new int has nothing to do with the storage duration of b. This is one of the reasons why using a smart pointer is recommend, so you don't have to worry about destroying the memory managed by b.

user6320840
  • 119
  • 2