8

I have this code and I wonder about memory allocation.

 void f(){
        static A a;
        //Other things...
    }

    class A {
        public:
           A();
        private:
            AnotherObjectType anotherObject;
    };

where will the anotherObject be allocated ? in the static code segment or elsewhere ? is there a risk for anotherObject to be overwritten ? (f will be called several times).

Emil Condrea
  • 9,705
  • 7
  • 33
  • 52
Pierre
  • 1,162
  • 12
  • 29

5 Answers5

5

All non-heap objects will be in the static segment, inside the static A instance of f().

Concerning overwriting, this could happen in older C/C++ if you used various singleton idioms in multi-threaded code. But e.g. newer gcc versions use the new standard requirements for automatic thread-safe initialization of static objects. See e.g. Is local static variable initialization thread-safe in C++11?

Community
  • 1
  • 1
Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
  • The only answer so far which points out difference in behavior of static variables in post and pre C++11 – senfen Apr 16 '15 at 08:49
  • 2
    More precisely, by non-*heap* you actually mean non-*dynamic*. The dynamically allocated objects can also be in the static segment if a custom allocator is used. "Heap" is an implementation detail which just happens to be most used. – Johann Gerell Apr 16 '15 at 08:50
  • Beware that I don't think Visual C++ implements thread safe static initialisation (magic statics) before VS2015. – sjdowling Apr 16 '15 at 08:54
  • @Johann Gerell: Good point, knowing about custom allocators is important. – Erik Alapää Apr 16 '15 at 08:54
1

Memory is either statically or dynamically allocated. Dynamic allocation is what you get when allocating memory at runtime, with for instance new and malloc. Static allocation is "the rest". Memory for class member variables are allocated with the class instance, so if it is statically allocated, the members end up in the same part of the memory, and if it is dynamically allocated, the members end up where the dynamic memory resides. This is also true for pointer member variables, but the actual memory it points at can be either dynamically (new and malloc) or statically allocated.

int i = 0;
int* pi = &i;     // pi points at statically allocated memory
pi = new int(0);  // pi points at dynamically allocated memory

So, if you have a static class instance, memory for it and its members is usually allocated in the code segment, but that is an implementation detail.

If the member is a pointer, which points at dynamically allocated memory, that memory will be where the used allocator decides. The "heap" is the most common implementation detail of dynamically allocated memory, which you normally get when using new and malloc, but a custom allocator can be used that controls memory elsewhere, even in the code segment.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
0

The variable a is a static variable and is only declared once, that means the A a; statement is only execute one time. The scope of the variable is above the function f scope. The field anotherObject is within the allocation of the A object.

See example with counting:

#include <iostream>
using namespace std;
class AnotherObjectType {};

class A {
public:
   A(){count = 0;};
    int count;
private:
    AnotherObjectType anotherObject;
};

 A f(){
    static A a;
    a.count++;
    //Other things...
    return a;
}

int main() {
    // your code goes here
    A a;
    for (int i = 0; i < 3; i++) {
        a = f();
        std::cout << "Count: " << a.count  << std::endl;
    }
    return 0;
}

Working Example: http://ideone.com/USqeEZ

See also: http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

Zelldon
  • 5,396
  • 3
  • 34
  • 46
0
void f(){
    /// this created in static segment - that's obviously for you
    static A a;
    //Other things...
}

class A {
    public:
       A();
    private:
        /// anotherObject is not pointer but explicit part of A,
        /// so it won't be created in heap or anywhere else,
        /// but in the same memory segment as an instance of A.
        AnotherObjectType anotherObject;
};

So, anotherObject wouldn't be overwritten because static A a create one instance of A in static segment and any other instances will be craeted in other segments depending in what segment you will create it.

Alex Medveshchek
  • 501
  • 4
  • 12
0

Although both called static, a static member is different from a static local variable.

A static member is shared in the class. Every instance of this class refers to the same member.

A static local variable is initialized once, and is not destroyed when the function returns.

In your code, non-static members are stored in the instance a, and a persists beyond function returns.

jdh8
  • 3,030
  • 1
  • 21
  • 18