declaring variable within a function

let's say, i have a function that needs to create a temporary variable to hold a number, i can do it statically, and dynamically. And below are two examples:

1
2
3
4
5
int function(int one, int two){
    int *num = new int;
    num = one + two;
    return *num;
}


vs

1
2
3
4
int function(int one, int two){
    int num = one + two;
    return num;
}


In the first one, do i need to manually delete the new int ? or it will be deleted automatically by default destructor?

And in the second one, how long does the static int num stay in memory ? does it get deleted after the function is out of scope ? And because it is declared within the function, it is not reachable from outside of the function, correct ?

And finally, which one is better ? and what is the difference ? like memory allocation, and stuffs like that.
http://www.cplusplus.com/forum/general/138037/#msg731921


> In the first one, do i need to manually delete the new int ?
¿where would you delete it?
you can't delete it inside the function as you need to return the value stored
you can't delete it outside the function because you lose access to it

it's a leak.

> or it will be deleted automatically by default destructor?
the destructor of a pointer does nothing
so, i should stick with the second one ?
> so, i should stick with the second one ?

Yes. Yes.

The return value can be an anonymous temporary:
1
2
3
int function( int first, int second ) {
    return first+ second ;
}

Yes. Yes.

The return value can be an anonymous temporary:
1
2
3
int function( int first, int second ) {
return first+ second ;
}



I know, but I just want to know the difference, and sometimes you cannot do that, for example, i might be adding up two class objects or structs, you know what i mean ?

The reason i opened this thread is because i wanna know what happens if i use the first option, and what happens if i use the second one. And what are the advantages and disadvantages...etc.

Value semantics is easier than pointer semantics.
i = j * k ; vs. if(pi) *pi = pj && pk ? *pj * *pk : 0 ;

The lifetime of objects with an automatic storage duration is automatically restricted to the block in which they are defined. And they are naturally exception safe; no local RAII wrapper is needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void foo()
{
    std::string simple = "this is easy" ; // automatic

    bar() ; // we don't care if this throws; the memory held by the string will be released.

    // ....

    int* pi = new int(100) ; // dynamic

    bar() ; // what happens to 'pi' if bar throws

    return ; // error: delete pi missed

    delete pi ;

    // ...

    std::unique_ptr<int> pj = std::make_unique<int>(100) ; // dynamic, wrapped
    int k = 100 ; // automatic

    bar() ; // ok if this throws; pj is exception safe; 
    // even so, k is a lot easier to use, and k is also far more efficient
}


Automatic storage duration is almost always the right storage duration for an object that is not required after the local block scope is exited.
Last edited on
i might be adding up two class objects or structs

Makes no difference. One can define addition for classes and structs just like the language has defined addition for int.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Foo {
// ...
public:
  Foo & operator+= ( const Foo & rhs );
};

Foo operator+ ( Foo lhs, const Foo & rhs ) {
  return (lhs += rhs);
}


Foo function( Foo first, Foo second, Foo third ) {
    return first + second + third;
}
And in the second one, how long does the static int num stay in memory ?

A point of terminology: num isn't static in your example. It is local.
does it get deleted after the function is out of scope?

Locals get deleted when the block that contains them goes out of scope. Since the block containing num is the function, then "yes" it gets deleted when the program flow leaves the function.
And because it is declared within the function, it is not reachable from outside of the function, correct ?

Correct. By the way, you might think "hey, what if I return a pointer to num? Can I see it then?" Then answer is no. The memory occupied by num will get reused for other local variables by other functions, so even if you did return a pointer to it, the pointer would point to garbage. Note also that the address of num can change from one call to the next. It truly is a variable that is created, has a lifetime and then gets destroyed.

And finally, which one is better ? and what is the difference ? like memory allocation, and stuffs like that.

Well you're leaking the memory in your pointer example, so that's definitely bad. But even if you didn't leak it, a local variable is usually preferable to one allocated on the heap:
- Allocating a local variable often requires ZERO extra time. When you call a function, the program usually adjusts the stack pointer. If it has to make room for an extra local variable then that just changes the value that gets added/subtracted from the stack pointer.
- In contrast, allocating (and later freeing) space on the heap requires a bunch of instructions.
- Note that the difference here is in the time to allocate space for the variable. The time required to construct (and destroy) it will be the same in either case.

So when should you put a local variable on the heap? When it's big. Programs allocate a relatively small amount of space to the stack. If you put a 5 megabyte array there, then you're likely to run out of stack space. You might want to consider this for anything larger than a kilobyte or so.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int function( int first, int second ) {
    
    // local variable with automatic storage duration
    // name is local to this block scope
    // initialised each time each time the following declaration-statement is executed
    // life-time lasts till the block is exited from
    int local_automatic =  first+ second ;


    // local variable with static storage duration
    // name is local to the block scope
    // zero-initialised before or at program start
    // initialized the first time control passes through the following declaration-statement 
    // life-time lasts till main() returns
    static int  local_static = first - second ;

    return local_static  * local_automatic ;
}



> So when should you put a local variable on the heap?

Any local variable (whether with static or automatic storage duration) must have a name.
An object with dynamic storage duration can't be given a name; it is anonymous.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
// pi is a local variable with automatic storage duration
// the type of pi is 'pointer to int'
// the object of type 'int' that it points to does not have a name
// life-time of pi is till the block is exited from
// life-time of the anonymous object of type 'int' that pi points to 
// is till a delete-expression with a pointer to that object is executed
int* pi = new int(5) ;


// seq is a local variable with automatic storage duration
// life-time of seq is till the block is exited from
// or the stack is unwound because of an exception
// when iys life time is over, its destructor does the clean-up
std::vector<char> seq( 5 * 1024 * 1024 ); // 5MB

// with the example of the vector in mind, it should be easy to see that this is a bad idea
char* pc = new char[  5 * 1024 * 1024 ]{} ; // 5MB

// ...
}

A point of terminology: num isn't static in your example. It is local.
does it get deleted after the function is out of scope?

Locals get deleted when the block that contains them goes out of scope. Since the block containing num is the function, then "yes" it gets deleted when the program flow leaves the function.
And because it is declared within the function, it is not reachable from outside of the function, correct ?

Correct. By the way, you might think "hey, what if I return a pointer to num? Can I see it then?" Then answer is no. The memory occupied by num will get reused for other local variables by other functions, so even if you did return a pointer to it, the pointer would point to garbage. Note also that the address of num can change from one call to the next. It truly is a variable that is created, has a lifetime and then gets destroyed.

And finally, which one is better ? and what is the difference ? like memory allocation, and stuffs like that.

Well you're leaking the memory in your pointer example, so that's definitely bad. But even if you didn't leak it, a local variable is usually preferable to one allocated on the heap:
- Allocating a local variable often requires ZERO extra time. When you call a function, the program usually adjusts the stack pointer. If it has to make room for an extra local variable then that just changes the value that gets added/subtracted from the stack pointer.
- In contrast, allocating (and later freeing) space on the heap requires a bunch of instructions.
- Note that the difference here is in the time to allocate space for the variable. The time required to construct (and destroy) it will be the same in either case.

So when should you put a local variable on the heap? When it's big. Programs allocate a relatively small amount of space to the stack. If you put a 5 megabyte array there, then you're likely to run out of stack space. You might want to consider this for anything larger than a kilobyte or so.



thank you, well explained

Makes no difference. One can define addition for classes and structs just like the language has defined addition for int.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Foo {
// ...
public:
Foo & operator+= ( const Foo & rhs );
};

Foo operator+ ( Foo lhs, const Foo & rhs ) {
return (lhs += rhs);
}


Foo function( Foo first, Foo second, Foo third ) {
return first + second + third;
}


thanks, i know i can do it that way, but i just wanna know the difference, but thank you for the reply


{

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

int function( int first, int second ) {
    
    // local variable with automatic storage duration
    // name is local to this block scope
    // initialised each time each time the following declaration-statement is executed
    // life-time lasts till the block is exited from
    int local_automatic =  first+ second ;


    // local variable with static storage duration
    // name is local to the block scope
    // zero-initialised before or at program start
    // initialized the first time control passes through the following declaration-statement 
    // life-time lasts till main() returns
    static int  local_static = first - second ;



So when should you put a local variable on the heap?

Any local variable (whether with static or automatic storage duration) must have a name.
An object with dynamic storage duration can't be given a name; it is anonymous.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// pi is a local variable with automatic storage duration
// the type of pi is 'pointer to int'
// the object of type 'int' that it points to does not have a name
// life-time of pi is till the block is exited from
// life-time of the anonymous object of type 'int' that pi points to 
// is till a delete-expression with a pointer to that object is executed
int* pi = new int(5) ;


// seq is a local variable with automatic storage duration
// life-time of seq is till the block is exited from
// or the stack is unwound because of an exception
// when iys life time is over, its destructor does the clean-up
std::vector<char> seq( 5 * 1024 * 1024 ); // 5MB

// with the example of the vector in mind, it should be easy to see that this is a bad idea
char* pc = new char[  5 * 1024 * 1024 ]{} ; // 5MB

// ...
}





thank you man, you are being very helpful
Last edited on
Topic archived. No new replies allowed.