0

I want to create an array of objects with non-default Constructor. Please note that I am not allowed to use vector from STL, I made a research on this and found a method:

Obj* p_obj[3];// for an array of 3 for example
// then allocate to each pointer using new
p_obj[0] = new Obj(10);
p_obj[1] = new Obj(15);
p_obj[2] = new Obj(20);

though when I am trying to create a bigger array(100 elements), my program goes segFault. I would appreciate if someone would advice me a good solution for this problem.

Thank you in advance!

Oleksandr
  • 97
  • 1
  • 9

2 Answers2

1

First of all, your code is completely correct. If it crashes, it must be a memory error elsewhere.

Second, your code is inefficient by allocating so many small objects individually and use double indirection. The key to how vector works (by default) is placement new. Example usage:

Obj* objects = static_cast<Obj*>(operator new(sizeof(*objects) * n));
for (size_t i = 0; i < n; ++n)
    new (objects + i) Obj("Constructor arguments...")

When you delete, you have to manually call the destructor of individual elements before deallocating the storage. That is

for (size_t i = 0; i < n; ++n)
    objects[i].~Obj();
operator delete(objects);

It is recommended to use a RAII wrapper to do the above allocation and deallocation.

And besides, why are you not allowed to use vector from STL?

Siyuan Ren
  • 6,627
  • 3
  • 40
  • 55
0

Well if you can't use vector

struct myVector
{
private:
  Obj *p_obj;
  std::size_t size_;
public:
  myVector(): size_(0) 
  {
  }
  /*
  myVector(int const &size): size(size_)
  { 
    p_obj = new Obj[size_]; 
  }
  */

  ~myVector()
  { 
    if(size_ != 0)
    {
      delete[] p_obj;
    }
  }

  void resize(int const&size) 
  {
     // delete or append new memory
  }

  void push_back(int const &rhs)
  {
     // push here, check size and allocate needed memory
  }

  Obj *begin()
  {
     // Check size and return first element
  }

  Obj *end()
  {
     // Check size and return end element
  }
}

This is very basic stuff, you also could use an iterator encapsulation which would save you a lot of headaches.

If this is for class it would be useful to come up with your own vector based on the vector functionality.

Claudiordgz
  • 2,999
  • 1
  • 20
  • 43
  • 1
    Uhm, no. new Obj[size_] requires that Obj has a default constructor. – wolfgang Mar 19 '14 at 23:09
  • Also, myVector() {} will cause a crash because it leaves p_obj uninitialized. Don't do that. And why are you passing integers by const reference? – wolfgang Mar 19 '14 at 23:15
  • there... push_back added for that specific functionality... private pointer with accesors too... at this rate we'll end up creating the vector class... I think if this is homework he should define the methods himself... don't you think? – Claudiordgz Mar 19 '14 at 23:15
  • Oh and I think it is irrelevant for this case to pass by value or by reference, but I'm not changing the parameter inside so it is more clear. The Standard does not say anything about one thing or the other as of 2013. – Claudiordgz Mar 19 '14 at 23:24
  • The vector header file is a header file that contains other 7 header files, and the stl_vector is a template of over 1400 lines long. The purpose is to help, but not give the solution entirely, not to tell him to quit altogether. Reading the standard is one thing, reading the code in the standard is other. It is overkill. – Claudiordgz Mar 19 '14 at 23:29
  • Oleksandr said, "I want to create an array of objects with non-default Constructor." In your code, each object gets initialized with the default constructor. – wolfgang Mar 19 '14 at 23:30
  • @wolfgang, I heard you the first time and made changes. Create an emtpy myVector object, then define push_back to use the functionality you need. The destructor works on the size property so it should be safe as it will not try to delete an uninitialized pointer. – Claudiordgz Mar 19 '14 at 23:32