Thread: size of dynamically allocated block of memory

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    87

    size of dynamically allocated block of memory

    Why does the output for the dynamically allocated array show 1 vs the fixed array shows 0 even though both are don't have elements initially.

    It seems trivial...
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int* dynamic_list = new int[7];
        
        int dynamic_list_size = sizeof(dynamic_list)/sizeof(int);
        
        cout << dynamic_list_size << endl;
        
        int list[] = {};
        int list_size_ = sizeof(list)/sizeof(int);
        cout << list_size << endl;
      return 0;
    }

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Because sizeof(dynamic_list) is equal to the size of an int,and you divide it by the size of an int so it gives you one.
    The list however is empty so, what are doing is actually zero/sizeof(int)=0.In my system sizeof(int)=4

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    if you're using new to make arrays, you have to keep track of the size. the system does not do it for you like in other languages.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by std10093 View Post
    Because sizeof(dynamic_list) is equal to the size of an int*,and you divide it by the size of an int so it gives you one.
    Fixed.
    Remember that dynamic_list is a pointer, not an array, so you are getting the size of the pointer.

    Code:
    int list[] = {};
    Empty lists do not compile. What compiler do you actually use?

    This seems to be your new thread on the subject of the same thing. You seem to fail to understand that there is no "empty" element in C++. Either there is an element, or there isn't. Your dynamic_lists have 7 elements, all of them filled with garbage.
    Your list declaration is wrong; it shouldn't compile because arrays with 0 elements are not allowed.

    And I know the next question is: how do I get the size?
    When using new, there is no portable way to do that. Some compilers implement vendor dependent functions that allow this, but I strongly suggest you avoid them. You have to keep track of the size yourself.
    However, like I mentioned in one of your other threads, you should be using std::array or std::vector instead of new and delete. They keep track of the size themselves, they manage memory for you, aid in debugging and are exception safe. All you need from a good piece of code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Sizeof is a compile time operation in C++. It cannot be used to compute the size of anything dynamic. (In C there is an exception to this).

    Also, it's not correct to say that the array returned by new has no elements in it. It creates an array with 7 elements in it. For primitives like int, using that syntax you cannot legally access their value, until you assign something else to them. Doing so would invoke undefined behaviour, which mean anything can happen. In practice the value is some arbitrary value, if you do this. If you instead want to 0 initialize the array, you can do this:
    Code:
    int* dynamic_list = new int[7]();
    Most of the time you should prefer not to use primitive arrays, and use std::vector instead. Unlike arrays, a vector can grow and shrink in size, as you add or remove elements from them.

    And as Elysia says, you cannot have an array of 0 elements like you have there. It will not compile on a compliant compiler.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    My tinkering:

    Code:
    #include <iostream>
    #include <algorithm>
    
    int main()
    {
        size_t dynamic_list_size = 7;
        // We need a size for the dynamic list *before* we make the list.
        int *list = new int[dynamic_list_size];
    
        for (size_t i = 0; i < dynamic_list_size; i++)
        {
            list[i] = 2 * (i + 1);
        }
    
        // Now supposing that you want to make a separate copy stored
        // on the stack...
        int stacklist[(const size_t)dynamic_list_size];
        // Note the use of a constant expression - it's required.
    
        std::copy(list, list + dynamic_list_size, stacklist);
        // Of particular note, we are copying ints to an int array. So
        // there is no real danger of code like "delete[] list;" making
        // stacklist being full of invalid pointers.
    
        // Read http://www.cplusplus.com/reference/algorithm/copy/ too.
    
        // Let's just see if they are the same.
        for (size_t i = 0; i < dynamic_list_size; i++)
        {
            std::cout << "list[" << i << "] = " << list[i] << "\t";
            std::cout << "stacklist[" << i << "] = " << stacklist[i] << std::endl;
        }
    
        delete[] list; // Release list because it was newed
    
        // stacklist will fall out of scope and be destroyed.
        return 0;
    }
    Now go from there.

    It really isn't all that difficult once you get the hang of it, but the point of C++ is that now you don't necessarily have to think about these low-level processes with classes like array and vector. You also won't learn stuff, like what goes on in vector<T>::insert(), so it can impede your understanding of how the array data structure actually works somewhat, unless you avoid using insert(). My personal opinion is that vector and friends are helpful and you should start out with them... but it can be fun to restrict yourself and learn more. Just my $0.02.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    >>int stacklist[(const size_t)dynamic_list_size];
    You can't do that.
    error C2057: expected constant expression
    error C2466: cannot allocate an array of constant size 0
    error C2133: 'stacklist' : unknown size

    You need a constant expression. Make dynamic_list_size const.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Code:
    int stacklist[(const size_t)dynamic_list_size];
    That's not a constant expression just because you wish it was a constant expression.

    "G++" is allowing this because it allows the "dynamic stack arrays" from C99 even in C++.

    Code:
    const size_t dynamic_list_size = 7;
    If you want a real constant expression, you have to stick with only bits that are constant expressions.

    Soma

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    "G++" is allowing this because it allows the "dynamic stack arrays" from C99 even in C++.
    Well isn't that just ........ing great.

    That isn't intuitive at all.

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Have you never noticed how many vendor specific extensions others here have perpetuated?

    It is best to use multiple compilers, but "-ansi -pedantic -std=c++98" or "-ansi -pedantic -std=c++0x" is your friend.

    [Edit]
    Actually, even some perfectly standard things have a weird relationship with the "Real World" where only a few compilers implement them correctly so you may wind up getting comfy with a standard feature with semantics that aren't widely available.
    [/Edit]

    Soma
    Last edited by phantomotap; 07-09-2012 at 04:20 PM.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Afaik, -ansi just equals -std=c++98 in C++ mode, so it shouldn't really be necessary.
    -Wall is a very good idea to have, though.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    The -ansi flags removes GNU extensions that conflict with ISO C++. And it doesn't mean the same as -std=C++98. You can use -ansi with any of the supported C++ standard. See the following link. Using the GNU Compiler and from that link:

    -ansi
    In C mode, support all ISO C89 programs. In C++ mode, remove GNU extensions that conflict with ISO C++.

    This turns off certain features of GCC that are incompatible with ISO C89 (when compiling C code), or of standard C++ (when compiling C++ code), such as the asm and typeof keywords, and predefined macros such as unix and vax that identify the type of system you are using. It also enables the undesirable and rarely used ISO trigraph feature. For the C compiler, it disables recognition of C++ style // comments as well as the inline keyword.

    The alternate keywords __asm__, __extension__, __inline__ and __typeof__ continue to work despite -ansi. You would not want to use them in an ISO C program, of course, but it is useful to put them in header files that might be included in compilations done with -ansi. Alternate predefined macros such as __unix__ and __vax__ are also available, with or without -ansi.

    The -ansi option does not cause non-ISO programs to be rejected gratuitously. For that, -pedantic is required in addition to -ansi. See Warning Options.

    The macro __STRICT_ANSI__ is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.

    Functions which would normally be built in but do not have semantics defined by ISO C (such as alloca and ffs) are not built-in functions with -ansi is used. See Other built-in functions provided by GCC, for details of the functions affected.
    Jim

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Hrm, this seems to be different from the page I looked at.
    I cannot speak for older versions, but for 4.7.1, it says:
    -ansi
    In C mode, this is equivalent to `-std=c90'. In C++ mode, it is equivalent to `-std=c++98'.

    This turns off certain features of GCC that are incompatible with ISO C90 (when compiling C code), or of standard C++ (when compiling C++ code), such as the asm and typeof keywords, and predefined macros such as unix and vax that identify the type of system you are using. It also enables the undesirable and rarely used ISO trigraph feature. For the C compiler, it disables recognition of C++ style `//' comments as well as the inline keyword.

    The alternate keywords __asm__, __extension__, __inline__ and __typeof__ continue to work despite -ansi. You would not want to use them in an ISO C program, of course, but it is useful to put them in header files that might be included in compilations done with -ansi. Alternate predefined macros such as __unix__ and __vax__ are also available, with or without -ansi.

    The -ansi option does not cause non-ISO programs to be rejected gratuitously. For that, -pedantic is required in addition to -ansi. See Warning Options.

    The macro __STRICT_ANSI__ is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.

    Functions that would normally be built in but do not have semantics defined by ISO C (such as alloca and ffs) are not built-in functions when -ansi is used. See Other built-in functions provided by GCC, for details of the functions affected.
    Source: C Dialect Options - Using the GNU Compiler Collection (GCC)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 02-29-2012, 02:25 PM
  2. Replies: 2
    Last Post: 10-18-2010, 07:52 AM
  3. Allocate memory inside allocated memory block?
    By Heidi_Nayak in forum C Programming
    Replies: 14
    Last Post: 04-15-2009, 04:19 PM
  4. Dynamically allocated size
    By maverickbu in forum C++ Programming
    Replies: 12
    Last Post: 06-26-2007, 01:16 PM
  5. Dynamically allocated memory
    By ^xor in forum Linux Programming
    Replies: 9
    Last Post: 06-28-2005, 11:42 AM