Initialization and Memory

Discussion in 'C++' started by Chris Forone, Jun 12, 2012.

  1. Chris Forone

    Chris Forone Guest

    Hello,

    if i write code like this:

    #include <vector>

    int main()
    {
    float big[] =
    {
    1.0f, 2.0f, 3.0f
    };

    std::vector<float> v(big, big + sizeof(big) / sizeof(big[0]));
    }

    are the floats twice in memory (one time from the literals, one time as
    copies in the vector)? do compilers free initialisation memory after
    initialization?

    thanks for your short answer,
    chris
     
    Chris Forone, Jun 12, 2012
    #1
    1. Advertising

  2. Chris Forone wrote:
    > if i write code like this:
    >
    > #include <vector>
    >
    > int main()
    > {
    > float big[] =
    > {
    > 1.0f, 2.0f, 3.0f
    > };
    >
    > std::vector<float> v(big, big + sizeof(big) / sizeof(big[0]));
    > }
    >
    > are the floats twice in memory (one time from the literals, one time as
    > copies in the vector)? do compilers free initialisation memory after
    > initialization?


    I think your question shows a misunderstanding of how C++ is compiled
    and run on common (read: nearly all) systems. There is not going to be
    a dynamic allocation (a call to malloc(), operator new(), etc.,) to
    "construct" the float array.

    The float values are going to exist, in one form or another, in the
    executable image, the executable file on disk. When the executable is
    executed aka run, the executable file is copied wholesale into memory
    (good enough for the purposes of this conversation). This is the first
    instance of those float values in memory. Then, the thing is scheduled
    and executed. We'll shortly get to main(), which will construct the
    std::vector, very probably by calling operator new() which likely does
    some bookkeeping and uses some underlying system calls to get you your
    memory. Then, the float values are copied to the dynamically allocated
    private internal array.

    The first instance of the float values exist in the executable image
    in the executable file, and AFAIK no common system is going to "free"
    memory from the original executable image. Sure, it may be paged out
    to disk, but any piece of memory may be paged out to disk (again good
    enough for the purposes of this conversation). The float values, along
    with the rest of the memory that was initially loaded as a copy of the
    executable file, will not be freed. Those virtual addresses will
    remain forever stuck holding those floats. No future stack object will
    "reuse" that memory, and no future call to malloc(), operator new(),
    etc., will "reuse" that memory and return it. Most (read: basically
    all) common systems will make no attempt at analyzing which pieces of
    the original executable image are no longer needed - giving up and
    just leaving the original executable image unchanged and untouched.
    The copy of the executable file is there for the life of the process.

    Of course - a conforming implementation can do whatever it wants as
    long as a conforming program couldn't tell the difference. That's the
    pedants answer. I tried to give a slightly more useful answer, and I
    will still emphasize that you shouldn't write broken code.

    I'm also still at a loss as to what your original intended question
    was. The answer I give can change greatly depending on the phrasing of
    your actual question. Are you asking if you should write code
    differently because of speed concerns? I need a better example then,
    as the OP code does nothing.
     
    Joshua Maurice, Jun 12, 2012
    #2
    1. Advertising

  3. Gareth Owen <> wrote:
    > Possibly even three times (once in the data
    > segment, copied onto the stack, then copied into the vector).


    The compiler might or might not be able to optimize copying such an array
    onto the stack in this case (if it can deduce that it's basically being used
    as a const array), but it's of course not guaranteed, and not even very
    probable.

    If the array taking stack space becomes a problem (quite unlikely, but if)
    then it can be solved by declaring it "static const" (or even better,
    "static constexpr" if using C++11). This will make the compiler (most
    probably) elide copying the array to the stack.

    An interesting question is what happens if the std::vector is constructed
    with an initializer list in C++11, ie:

    std::vector<float> v = { 1.0f, 2.0f, 3.0f };

    How many times will those values be in memory at worst?
     
    Juha Nieminen, Jun 12, 2012
    #3
  4. Chris Forone

    Chris Forone Guest

    thanks to all. i thought i can avoid a loader (because of portability)
    for huge 3d data and put all into headers (as arrays).

    chris
     
    Chris Forone, Jun 13, 2012
    #4
  5. Chris Forone

    Jorgen Grahn Guest

    On Wed, 2012-06-13, Chris Forone wrote:
    > thanks to all. i thought i can avoid a loader (because of portability)
    > for huge 3d data and put all into headers (as arrays).


    Why in headers rather than plain source files?

    Doing it like this is not uncommon:

    // foobar_image.cc
    const unsigned char foobar_jpeg[] = { 47, 211, 99, ... };

    //foobar_image.h
    ...
    const unsigned char foobar_jpeg[];

    // some other source file:
    #include "foobar_image.h"
    show_on_screen(foobar_jpeg);

    All the data is in the executable, and only appears there
    once. Same when the program executes (on any sensible machine).

    If you make it non-const, that may cause some inefficiency.

    Many people use tools to generate source files like foobar_image.cc
    from the actual data. Some image formats (e.g. the original PPM
    format) actually *are* C source code similar to the one above.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jun 13, 2012
    #5
  6. Chris Forone

    gwowen Guest

    On Jun 13, 3:21 pm, Jorgen Grahn <> wrote:

    > All the data is in the executable, and only appears there
    > once. Same when the program executes (on any sensible machine).


    (probably) better even than that, because if you're running multiple
    invocations of the same program:
    i) the data will be in memory (the file cache) == fast!
    ii) the cached data will be shared between invocations == efficient!
     
    gwowen, Jun 14, 2012
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    10
    Views:
    989
  2. Matthias Kaeppler
    Replies:
    2
    Views:
    469
    Victor Bazarov
    Jul 18, 2005
  3. Jess
    Replies:
    23
    Views:
    971
  4. Replies:
    5
    Views:
    2,065
    Arne Mertz
    Mar 26, 2009
  5. Taras_96
    Replies:
    3
    Views:
    609
    Michael Tsang
    Oct 30, 2009
Loading...

Share This Page