Creating uninitialized array

This is a discussion on Creating uninitialized array within the C++ Programming forums, part of the General Programming Boards category; Code: void *heap[size * sizeof(T)]; To access each element in array we could use: Code: T &operator [] (unsigned int ...

  1. #1
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489

    Creating uninitialized array

    Code:
    void *heap[size * sizeof(T)];
    To access each element in array we could use:
    Code:
    T &operator [] (unsigned int index)
    {
      return *reinterpret_cast< T * >(heap + index *sizeof(T));
    }
    Is there another way to create heap allocated array without initialization?

    Code:
    MyClass myObjects[1024];
    The code above will call the MyClass' default constructor 1024 times!
    Last edited by audinue; 08-28-2009 at 12:50 PM.
    Just GET it OFF out my mind!!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,271
    What exactly are you trying to do? If you are trying to emulate std::vector's ability to have a capacity greater than the size without constructing the objects that are not (yet) supposed to be in the vector, then one way is to use placement new.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Any example please?

    I tought placement new is for calling constructor on preallocated buffer.

    While in my case I don't want to call any constructor, just allocating the objects in an array.
    Just GET it OFF out my mind!!

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,271
    Quote Originally Posted by audinue
    I tought placement new is for calling constructor on preallocated buffer.
    Yes.

    Quote Originally Posted by audinue
    While in my case I don't want to call any constructor, just allocating the objects in an array.
    That does not make sense (for objects of class types). You are saying: I want to create objects to be stored in an array, but I do not want to create any objects.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Your statement need to be fixed.
    Quote Originally Posted by laserlight View Post
    I want to create objects to be stored in an array, but I do not want to INITIALIZING any objects.
    What I need is the UNINITIALIZED not UNCREATED objects stored in an array.

    It just ALLOCATING (think in low level manner) block of memory with size of objects multiplied to the elements count and associative with indexes, in other words an array.

    But if there is no way to do
    Code:
    T array[999999999999999999999]
    without initializing each elements easily, well said I'll use the topmost code of my first post then.
    Just GET it OFF out my mind!!

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,271
    Quote Originally Posted by audinue
    What I need is the UNINITIALIZED not UNCREATED objects stored in an array.
    In the context of objects of class types, there is no such thing (and arguably that is the case for objects of built-in types as well, though we often consider variables with garbage values to be uninitialised). Consequently, the act of creating an object initialises it.

    Perhaps you should be using an array of (smart) pointers instead. (As in an array of pointers to the given class type, not an array of pointers to void.)

    Quote Originally Posted by audinue
    It just ALLOCATING (think in low level manner) block of memory with size of objects multiplied to the elements count and associative with indexes, in other words an array.
    If you think of it that way, then placement new is correct because you are dealing with a buffer in which objects are constructed at will.
    Last edited by laserlight; 08-28-2009 at 02:12 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You can't have objects that didn't have their constructor called in a valid program. At some point you'll need to call the constructor, before you actually use the instance, and that is what placement new is for.

    Here's an example of such a class:

    Code:
    #include <iostream>
    #include <cassert>
    #include <string>
    #include <algorithm>
    #include <iterator>
    
    template <class T, unsigned Size>
    class Array
    {
        char buffer[Size * sizeof(T)];
        unsigned count;
    public:
        Array(): count(0) {}
        //also needed: copy constructor, assignment operator and destructor
    
        unsigned size() const { return count; }
        unsigned capacity() const { return Size; }
        void push_back(const T& value)
        {
            assert(size() < capacity());
            new (to_object(size())) T(value);
            ++count;
        }
        void pop_back()
        {
            assert(size() > 0);
            --count;
            to_object(size())->~T();
        }
    
        typedef const T* const_iterator;
        typedef T* iterator;
        typedef T value_type;
        typedef const T& const_reference;
    
        iterator begin() { return to_object(0); }
        iterator end() { return to_object(size()); }
        const_iterator begin() const { return to_object(0); }
        const_iterator end() const { return to_object(size()); }
    
    private:
        const T* to_object(unsigned index) const
        {
            return reinterpret_cast<T*>(buffer) + index;
        }
        T* to_object(unsigned index)
        {
            return reinterpret_cast<T*>(buffer) + index;
        }
    };
    
    int main()
    {
        std::string data[] = {"The", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"};
        const unsigned size = sizeof(data) / sizeof(data[0]);
        Array<std::string, size> array;
        std::copy(data, data + size, std::back_inserter(array));
        std::copy(array.begin(), array.end(), std::ostream_iterator<std::string>(std::cout, " "));
        while (array.size() > 0) {
            std::cout << '\n' << array.size();
            array.pop_back();
        }
    }
    Last edited by anon; 08-29-2009 at 07:56 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Why you guys telling me about placement new??

    Sorry, I already know that for, and initializing and destructing things is just easy for the next step.

    Code:
    void *heap[size * sizeof(T)];
    And sorry for my fault,... it should be stack not heap

    I think there is maybe some kind of syntax like:
    Code:
    T (do_not_initialize) array[1000];
    
    cout << array[index]; //hello uninitialized T element
    so we don't need to do
    Code:
    char buffer[size * sizeof(T)];
    T *array = reinterpret_cast<T*>(buffer);
    
    T &operator [] (unsigned int index) {
      return array[index];
    }
    Just GET it OFF out my mind!!

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think there is maybe some kind of syntax like
    But there isn't. Giving you easy access to unconstructed objects would be a major flaw in the language.

    You must use placement new to construct the object first. Except perhaps for built-in types and PODs but in this case you can just declare an array and have stuff uninitialized.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,013
    But why do you need to make sure you don't call the constructor in the first place?
    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.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,308
    There's a reason we don't try and use raw uninitialised memory as objects without having constructed them. It might crash!
    It will work fine if T is of type integer, but if it were say a std::string then when you tried to print the value without constructing it then it will almost cetainly crash.
    It's possible that you have a class that can work just fine in an uninitialised state, in which case it could make sense for the default constructor to do nothing. In such a case hopefully the constructor will get inlined, and the loop that calls the empty constructor will hopefully get optimised out entirely, making allocating an array of them O(1).
    One such class might be a class that just contains a 2D point:
    Code:
    class Point2D {
        int x;
        int y;
        // member functions omitted
    };
    Really, it's not up to the person writing the code to allocate the array to decide if the constructor does any work or not. It's up to the designer of the class. In the above class, the designer has perhaps effectively said that it's okay to not initialise its values, and you don't have to do anything to make them not be initialised. If the designer had added:
    Code:
        //Point2D() : x(0), y(0) {}
    Then they must not consider it okay for the class to not be initialised, and you should respect that. When the class contains pointers then there's a really good reason for that!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Profiler Valgrind
    By afflictedd2 in forum C++ Programming
    Replies: 4
    Last Post: 07-18-2008, 10:38 AM
  2. Creating array of structs
    By knirirr in forum C++ Programming
    Replies: 12
    Last Post: 06-18-2008, 09:30 AM
  3. Creating a menu that reads input via an array?
    By Nalif in forum C Programming
    Replies: 6
    Last Post: 09-29-2006, 10:21 PM
  4. Array Program
    By emmx in forum C Programming
    Replies: 3
    Last Post: 08-31-2003, 01:44 AM
  5. Creating an array of object pointers
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 10-08-2001, 11:01 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21