Copying an array - c++

I am trying to copy an array.
class Myobject
{
int nb;
string name;
Myobject* next;
Myobject(int nb, string name) {this->name=name; this->nb=nb; this->next=NULL;}
};
Myobject **array;
array= new Myobject*[100];
how can I make a deep copy of the Myobject ** and thus be able to modify one of the instances.

If you want to be up to date, use RAII for which C++ is really good for.
#include <vector>
#include <memory>
#include <string>
#include <iostream>
struct Myobject : std::enable_shared_from_this< Myobject >
{
int nb;
std::string name;
std::shared_ptr<Myobject> next;
Myobject(int nb, std::string name) { this->name=name; this->nb=nb; }
~Myobject() { std::cout << "deleting " << nb << " " << name << std::endl; }
};
int main() {
std::vector< std::shared_ptr< Myobject > > arr;
arr.push_back(std::make_shared< Myobject >(1,"first"));
arr.push_back(std::make_shared< Myobject >(2,"second"));
for (auto obj: arr) {
std::cout << obj->nb << " " << obj->name << std::endl;
}
arr[0]->next = arr[1];
};
outputting
1 first
2 second
deleting 1 first
deleting 2 second
and you don't need to care much about memory management at first. Your example without proper care would generate memory leaks.
Update: forgot to mention, if you have circular references, beware, you might get memory leaks using shared_ptrs as well. If that should be the case, you might avoid that by switching to weak_ptrs → std::weak_ptr

You may add this (deep)-copy constructor:
Myobject(const Myobject& rhs) :
nb(rhs.nb),
name(rhs.name),
next(rhs.next == NULL ? NULL : new Myobject(*rhs.next))
{}
You will probably have to add a correct destrutor to avoid memory leak...
If possible, I suggest to use std::list<Myobject> instead

Allocate array and loop to copy.
NewMyobject **newarray = new Myobject*[100];
for (int i = 0 ; i < 100; ++i)
newarray[i] = new MyObject(array[i]);
Object must have a copy constructor.

Related

verify that members of c++ objects have constant address during runtime with vector example

I am trying to convince myself that objects in C++ have constant address during their lifetime. Here is a minimal working example:
#include <iostream>
#include <type_traits>
#include <vector>
class Class1
{
public:
Class1(unsigned int * pt);
unsigned int * val_pt;
};
Class1::Class1(unsigned int * pt)
:
val_pt(pt)
{}
class Class2
{
public:
Class2(std::vector<unsigned int> vec_);
std::vector<unsigned int> vec_of_ints;
Class1 class1_instance;
};
Class2::Class2(std::vector<unsigned int> vec_)
:
vec_of_ints(vec_),
class1_instance(Class1(&vec_of_ints[0]))
{}
int main() {
std::vector<unsigned int> vec_test(10, 2);
Class2 instance_class2(vec_test);
Class1 instance_class1 = instance_class2.class1_instance;
//both addresses are equal
std::cout<<"Address stored in instance_class1: "<<instance_class1.val_pt<<" ,address of first vec_element of instance_class2: "<<&(instance_class2.vec_of_ints)[0]<<std::endl;
instance_class2.vec_of_ints.resize(20);
//different addresses now
std::cout<<"Address stored in instance_class1: "<<instance_class1.val_pt<<" ,address of first vec_element of instance_class2: "<<&(instance_class2.vec_of_ints)[0]<<std::endl;
return 0;
}
My Class2 stores a vector of ints and an instance of Class1. Class1 stores the address of the vector of the Class2 instance.
I'd like to get the address of that vector, i.e. the address where the vector is stored on the stack. If my understanding is correct, the resize() function doesn't change that address on the stack but only the content of that address, i.e. where the vector points to in heap.
My overall goal is to show that any modifications of the vector in Class2 are "visible" in the stored pointer of Class1. So if I dereference the pointer in Class1 I will get the same integer value as when accessing the vector itself in Class2. That is because the address of member variables are constant during runtime.
But I guess something is wrong in my code, probably in the constructor where I pass 'vec[0]'. I think this is not the actual address of the vector in the stack but some address on the heap. How do I get the correct address?
Any input is appreciated!
What you're doing here is ungodly, and needs to stop. Consider this particularly terrible pattern:
class DataOwner {
public:
inline std::vector<uint32_t>& getData() { return data; }
private:
// I am safely tucked away
std::vector<uint32_t> data;
};
class I_Want_To_Work_On_Data {
public:
I_Want_To_Work_On_Data(DataOwner* owner) : owner(owner) {}
void doThing() {
auto& direct_ref_to_data = owner->getData();
for(auto& item : direct_ref_to_data) {
// This is just as fast as your direct pointer :/
}
}
private:
DataOwner* owner;
};
Returning mutable access to the data is somewhat bad, but it's far safer than the approach you are taking (in a single threaded environment a least). Performance is no worse than what you are attempting, but it is a lot safer. So what are you optimising this for exactly? How is your approach an improvement over this boring pattern?
Now you could argue that providing mutable access to the std::vector isn't wanted (i.e. don't allow any old code to resize the array), but that can easily be solved without resorting to dirty hacks.
#include <vector>
#include <cstdint>
class DataOwner {
public:
inline std::vector<uint32_t>::iterator begin()
{ return data.begin(); }
inline std::vector<uint32_t>::iterator end()
{ return data.end(); }
inline std::vector<uint32_t>::const_iterator begin() const
{ return data.begin(); }
inline std::vector<uint32_t>::const_iterator end() const
{ return data.end(); }
private:
// I am safely tucked away
std::vector<uint32_t> data;
};
class ConstAccess {
public:
ConstAccess(const DataOwner& owner) : owner(owner) {}
void doThing() {
for(const auto& item : owner) {
}
}
private:
const DataOwner& owner;
};
class MutableAccess {
public:
MutableAccess(DataOwner& owner) : owner(owner) {}
void doThing() {
for(auto& item : owner) {
}
}
private:
DataOwner& owner;
};
The performance is the same as with your approach, however this approach as the following advantages:
It won't crash in debug builds on this line: class1_instance(Class1(&vec_of_ints[0])), when the vector is empty, and you attempt to dereference NULL to find the address.
It won't crash when you attempt to dereference unsigned int * val_pt; after you've accidentally resized the array.
It won't allow you to accidentally do: delete [] val_pt
I'm not sure what conclusions you extracted from the comments and responses above.
I just wanted to make sure these were not among them:
The address of a member variable is constant during runtime.
If, for example, you have a vector of Class2 instances, and you
resize that vector, the address of the vec_of_ints member variable
may change for any of those instances.
Having a Class2 instance in the stack or a pointer to a Class2 instance in the heap makes a difference.
The address of the vec_of_ints member variable shouldn't change if
you resize it, no matter the instance of Class2 is in the stack or
in the heap.
The example below tests both assertions (https://godbolt.org/z/3TYrnjro8):
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
struct HoldsIntVector
{
std::vector<int> v{};
};
int main()
{
HoldsIntVector stackInstance{};
auto heapInstance{std::make_unique<HoldsIntVector>()};
stackInstance.v.push_back(5);
heapInstance->v.push_back(5);
auto printStackAndHeapInstances = [&](const auto& text){
std::cout << std::showbase << std::hex;
std::cout << &stackInstance << "\t" << &heapInstance << "\t";
std::cout << &stackInstance.v << "\t" << &heapInstance->v << "\t";
std::cout << std::setw(8) << std::setfill('0') << stackInstance.v.data() << "\t\t";
std::cout << std::setw(8) << std::setfill('0') << heapInstance->v.data() << "\t\t";
std::cout << text;
std::cout << "\n";
};
std::cout << "stackInstance\theapInstance\tstackInstance.v\theapInstance.v\t&stackInstance.v[0]\t&heapInstance.v[0]\n";
printStackAndHeapInstances("after initializing stack and heap instances");
// After resizing both vectors in stack and heap instances
//
// Address of v doesn't change neither in stack nor in heap instances
// Address of v[0] changes in both stack and heap instances
stackInstance.v.resize(10);
heapInstance->v.resize(10);
printStackAndHeapInstances("after resizing both v's");
std::cout << "\n";
// Now what happens if we have a vector of HoldsIntVector and we resize it
//
// Address of v changes for the first HoldsInVector
std::vector<HoldsIntVector> hivs{10};
std::for_each(begin(hivs), end(hivs), [](auto& hiv){hiv.v.push_back(3);});
std::cout << "&hivs[0].v\n" << &hivs[0].v << "\t" << "after intializing hivs\n";
hivs.resize(20);
std::cout << &hivs[0].v << "\t" << "after resizing hivs\n";
}

Array of objects without default constructors on the stack?

I can achieve the functionality I need using option 3, however I would like to investigate whether it is possible to create the array on the stack instead.
#include <array>
#include <vector>
struct NotDefaultConstructable
{
NotDefaultConstructable(int val){};
};
int main()
{
//std::array<NotDefaultConstructable, 5> aA; // Fails to compile. [On stack]
//std::vector<NotDefaultConstructable> aV(5); // Fails to compile. [On heap]
std::vector<NotDefaultConstructable> aV; // Compiles. [ On heap]
aV.reserve(5);
}
std::array is an aggregate class type which may have a trivial, implicitly defaulted constructor. If T is not default-constructible, the implicit default constructor is defined as deleted, as per [class.ctor]/5.3.
As this applies in your case, you cannot construct an object of std::array<NotDefaultConstructable, 5> by default construction. You can, however, construct it by means of aggregate initialization:
#include <array>
struct NotDefaultConstructable {
NotDefaultConstructable(int){};
};
int main() {
std::array<NotDefaultConstructable, 3> arr{1, 2, 3};
}
In this sense, all elements of a std::array object should arguably be initialized, even if they represent a non-present object (yet to be "filled", if you will).
You could either find a an appropriate static vector container, such as boost::static_vector, or you could e.g. implement a thin wrapper around std::array which stores an array as above as well its runtime size. Another alternative would be to use a std::array of optionals:
#include <array>
#include <iostream>
#include <optional>
struct NotDefaultConstructable {
NotDefaultConstructable(int val) : val_(val) {};
int val_;
};
int main() {
std::array<std::optional<NotDefaultConstructable>, 3> arr{};
arr[1] = NotDefaultConstructable{42};
for(const auto& element : arr) {
if(element.has_value()) {
std::cout << "has value: " << element.value().val_;
} // has value: 42
}
}
where no dynamic memory allocation takes place (cppreference):
If an optional contains a value, the value is guaranteed to be allocated as part of the optional object footprint, i.e. no dynamic memory allocation ever takes place.
Judging by the fact that OP mentioned looking into using placement new, I wanted to make a full example of using a stack allocated array as memory for dynamically constructed objects.
Using this method, you can allocate stack memory without initializing it with instances. The problem, however, is that you have to monitor the object lifetime for each instance yourself. In this example, I construct all of them and can then simply assume that all of them have to be destroyed, however monitoring how many instances are alive and should be destroyed is quite messy.
This is why dfrib's answer is much more suitable in your situation, as it allows you to allocate the memory on the stack using std::array<std::optional<Type>, 5> and assign instances later. Object lifetime will also be managed for you, so is much more advisable.
Example 1: Placement New:
#include <array>
#include <iostream>
struct NotDefaultConstructable {
int Value;
NotDefaultConstructable(int val) : Value(val) {
std::cout << "constructed: " << Value << "\n";
};
~NotDefaultConstructable(){
std::cout << "destructed: " << Value << "\n";
}
};
int main() {
// allocate enough memory on the stack for 5 instances
char aV[sizeof(NotDefaultConstructable) * 5];
// get a pointer to the first NotDefaultConstructable in that array
auto avArray = static_cast<NotDefaultConstructable*>(static_cast<void*>(&aV[0]));
// use placement new to construct each instance
for (auto i = 0; i < 5; ++i)
new (&avArray[i]) NotDefaultConstructable((i + 1) * 2);
// do stuff with the instances
for (auto i = 0; i < 5; ++i)
std::cout << "instance: " << avArray[i].Value << "\n";
// destruct them all manually, this is what makes placement new a little
// cumbersome. I would advise to use std::optional instead.
for (auto i = 0; i < 5; ++i)
avArray[i].~NotDefaultConstructable();
}
example 1: https://godbolt.org/z/7jW8Pb
Example 2: std::array with std::optional
Here's an example using std::optional, which has minor overhead (about ~4 bytes per object) to achieve much more convenience:
#include <array>
#include <optional>
#include <iostream>
struct NotDefaultConstructable {
int Value;
NotDefaultConstructable(int val) : Value(val) {
std::cout << "constructed: " << Value << "\n";
};
~NotDefaultConstructable(){
std::cout << "destructed: " << Value << "\n";
}
};
int main() {
// allocate enough memory on the stack for 5 instances
std::array<std::optional<NotDefaultConstructable>, 5> avArray;
// use placement new to construct each instance
for (auto i = 0; i < 5; ++i)
avArray[i] = NotDefaultConstructable((i + 1) * 2);
// do stuff with the instances
for (auto i = 0; i < 5; ++i)
std::cout << "instance: " << avArray[i].value().Value << "\n";
}
example 2: https://godbolt.org/z/Ynx8aE
You can try the following
#include <iostream>
struct NotDefaultConstructable {
NotDefaultConstructable(int val) {
};
};
int main() {
NotDefaultConstructable aV[5] { 6, 6, 6, 6, 6 };
}

std::vector with elements allocated on the heap - do I need rule of 5?

If I have a class with members like this:
class MyClass {
public:
void set_my_vector() {
for (int ind = 0; ind < 3; ++ind) {
my_vector.push_back(new MyStruct(i, i*2));
}
}
private:
struct MyStruct {
int num_a;
int num_b;
MyStruct(int i, int j) : num_a(i), num_b(j) {}
};
std::vector<MyStruct*> my_vector;
};
Do I need to write the rule-of-five functions, or will std::vector take care of deep copying and deleting the elements allocated on the heap?
EDIT:
The following code uses default copy constructor, so I assume that after I copy my_class1 object into my_class2 object, the elements of my_class1.my_vector and my_class2.my_vector will be the same, because the MyStruct pointers were copied, but not the data itself. However, the output shows that they are not the same. You can run the code here: https://onlinegdb.com/S1pK9YE4v
#include <iostream>
#include <vector>
class MyClass {
public:
void fill_my_vector(int i, int j) {
my_vector.clear();
for (int ind = 0; ind < 3; ++ind) {
my_vector.push_back(new MyStruct(i, j));
}
}
void print () {
for (int ind = 0; ind < 3; ++ind) {
std::cout << my_vector[ind]->int1 << ", " << my_vector[ind]->int2 << std::endl;
}
std::cout << std::endl;
}
private:
struct MyStruct {
MyStruct (int i, int j) :
int1(i), int2(j)
{}
int int1;
int int2;
};
std::vector<MyStruct*> my_vector;
};
int main()
{
MyClass my_class1;
my_class1.fill_my_vector(42, 43);
std::cout << "my_class1: " << std::endl;
my_class1.print();
MyClass my_class2 = my_class1;
my_class2.fill_my_vector(12, 13);
std::cout << "my_class2: " << std::endl;
my_class2.print();
std::cout << "my_class1: " << std::endl;
my_class1.print();
}
EDIT2: I know about smart pointers. I am specifically interested what happens if I use raw pointers.
You need to implement the copy constructor, copy assignment and destructor.
Additionally, consider changing your vector declaration from
std::vector<MyStruct*> my_vector;
to
std::vector<std::unique_ptr<MyStruct>> my_vector;
so that it actually owns the heap allocated objects properly. Doing this change will help you not write a destructor.
No, std::vector doesn't take care of deep copying of your objects stored by pointer. You have few possibilities to solve this:
Store MyStruct by value.
Store std::unique_ptr<MyStruct>.
Store std::shared_ptr<MyStruct>.
Note that because MyStruct contains only fields of the primitive types, neither of copy constructor, assignment operator and destructor are needed, otherwise you'd have to implement them, default implementation which compiler will generate automatically will be good enough.

Correct way to claim ownership of existing raw pointer

I have some code that claims ownership of a sequence of raw pointers, and am wondering if there is an acceptable way to do this? What I'm looking for is a way to enforce the ownership in code to a greater degree. Mainly, I've been wondering whether or not my constructor should be taking a vector of unique pointers directly.
As a sidenote, once ownership has been claimed, the data is supposed to be immutable.
The code follows roughly the pattern of class X below.
#include <iostream>
#include <memory>
#include <vector>
using namespace std; // For readability purposes only
class X {
public:
const vector< unique_ptr<const int> > data; // In my case this is private
// Constructor: X object will take ownership of the data
// destroying it when going out of scope
X (vector<int*> rawData)
: data { make_move_iterator(rawData.begin()), make_move_iterator(rawData.end()) }
{ }
};
int main() {
// Illustrating some issues with claiming ownership of existing pointers:
vector<int*> rawData { new int(9) , new int(4) };
int* rawPointer = rawData[0];
{ // New scope
X x(rawData);
cout << *(x.data[0]) << endl; // Unique pointer points to 9
*rawPointer = 7;
cout << *(x.data[0]) << endl; // Unique pointer points to 7
}
cout << *rawPointer << endl; // The pointer has been deleted, prints garbage
return 0;
}
It is difficult to post an answer without detailed knowledge of your situation. But my recommendation is to attach your data to a unique_ptr as soon as it is known. Then you can move that unique_ptr into and out of vectors at will. For example:
#include <iostream>
#include <memory>
#include <vector>
using namespace std; // For readability purposes only
class X {
public:
const vector< unique_ptr<const int> > data; // In my case this is private
// Constructor: X object will take ownership of the data
// destroying it when going out of scope
X (vector<unique_ptr<const int>>&& v)
: data { std::move(v) }
{ }
};
vector<unique_ptr<const int>>
collectRawData()
{
auto rawData = {9, 4};
vector<unique_ptr<const int>> data;
for (auto const& x : rawData)
data.push_back(make_unique<int>(x));
return data;
}
int main() {
auto rawData = collectRawData();
{ // New scope
X x(std::move(rawData));
cout << *(x.data[0]) << endl; // Unique pointer points to 9
cout << *(x.data[1]) << endl; // Unique pointer points to 4
}
}
You did several misstakes.
In case of const vector< unique_ptr<const int> > data; a move iterator does make not that much sense. The reason why is, int* doesn't have a move constructor.
If you call X's constructor X (vector<int*> rawData) with vector < int* > so the copy constructor of vector < int* > gets called, but that's not what you want to.
Btw. the reason why to use move is, to avoid big memory copies. For instance std::vector < int* >: The member attribute size and the pointer to the memory location where your int*s are stored of std::vector<int*> must be copied by a move too but not the int*s self. A conclusion is that move is there to claim ownership.
If you want shared pointers like that, use std::shared_ptr. It owns a counter, which counts the ptrs which pointing to itself.
´
My Example Code:
class X
{
public:
const std::vector< std::shared_ptr< const int> > data; // In my case this is private
// Constructor: X object will take ownership of the data
// destroying it when going out of scope
X (std::vector<std::shared_ptr<int>>& rawData)
//: data(rawData)
: data(rawData.cbegin(), rawData.cend())
{ }
};
int main() {
// Illustrating some issues with claiming ownership of existing pointers:
std::vector<std::shared_ptr<int>> rawData { std::make_shared<int>(9), std::make_shared<int>(4) };
int* rawPointer = rawData[0].get();
{ // New scope
X x(rawData);
cout << *(x.data[0]) << endl; // Unique pointer points to 9
*rawPointer = 7;
cout << *(x.data[0]) << endl; // Unique pointer points to 7
}
cout << *rawPointer << endl; // The pointer has been deleted, prints not more garbage
return 0;
}
If you dont want use std::shared_ptr, you will need an GC.

Create an array of class objs

Consider following class
class test
{
public:
test(int x){ cout<< "test \n"; }
};
Now I want to create array of 50 objects of class test . I cannot change class test.
Objects can be created on heap or stack.
Creating objs on stack is not possible in this case since we dont have default constructor in class
test objs(1)[50]; /// Error...
Now we may think of creating objs on heap like this..
test ** objs = NULL;
objs = (test **) malloc( 50 * sizeof (test *));
for (int i =0; i<50 ; ++ i)
{
objs[i] = new test(1);
}
I dont want to use malloc .Is there any other way??
If you guys can think of some more solutions , please post them...
You cannot create an array of objects, as in Foo foo [N], without a default constructor. It's part of the language spec.
Either do:
test * objs [50];
for() objs[i] = new test(1).
You don't need malloc(). You can just declare an array of pointers.
c++decl> explain int * objs [50]
declare objs as array 50 of pointer to int
But you probably ought to have some sort of automatic RAII-type destruction attached.
OR subclass test publicly:
class TempTest : public test
{
public:
TempTest() : test(1) {}
TempTest(int x) : test(x) {}
TempTest(const test & theTest ) : test(theTest) {}
TempTest(const TempTest & theTest ) : test(theTest) {}
test & operator=( const test & theTest ) { return test::operator=(theTest); }
test & operator=( const TempTest & theTest ) { return test::operator=(theTest); }
virtual ~TempTest() {}
};
and then:
TempTest array[50];
You can treat every TempTest object as a test object.
Note: operator=() & copy constructor are not inherited, so respecify as necessary.
Why do you need array?
std::vector<test*> v(50);
Or as #j_random_hacker suggested in the comments:
std::vector<test> v(50, test(1));
An example:
/** g++ -Wall -o vector_test *.cpp && vector_test */
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
struct Test {
int value;
Test(int x) : value(x)
{
std::cout << "Test(" << value << ")" << " ";
}
operator int() const
{
std::cout << "int(" << value << ")" << " ";
return value;
}
};
int main()
{
using namespace std;
vector<Test> v(5, Test(1));
cout << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
v[1] = 2;
v[2].value = 3;
cout << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Output:
Test(1)
int(1) 1 int(1) 1 int(1) 1 int(1) 1 int(1) 1
Test(2)
int(1) 1 int(2) 2 int(3) 3 int(1) 1 int(1) 1
Contrary to what many people believe, you can actually create an array of objects that do not have a default constructor. What you cannot do is make it use a set of arguments for all constructor invokations. You just have to initialize all elements of it. That is, you can do the following:
#define PRINTT(z, n, initializer) initializer
test objs[50] = {
BOOST_PP_ENUM(50, PRINTT, 1) // yields 1, 1, 1, .... 1
};
#undef PRINTT
That will initialize all 50 elements with 1. boost::pp is used to print a 1 50 times in a row automatically.
I think that other responders are treating this question too literally.
If all you really want to do is make a "group" of 50 objects that you can treat as an array, then by far the easiest and most maintainable way of accomplishing what you're trying to do is:
std::vector<test> objs(50, test(1));
This declares a vector of 50 objects, each of which is a copy of test(1). A vector is basically a C++ growable array; although you may not need the growability, the fact that it can be called with a 2-arg constructor that copy-constructs each element is useful here.
You can use this more-or-less exactly like an array -- e.g. the 5th element is objs[4]. Performance is the same too -- the C++ standard guarantees that internally the elements are stored in a contiguous array.
You don't need malloc(). You can use new for the array of pointers, too:
test **objs = new test* [50];
Boost's Pointer Container library might come to rescue here. With boost::ptr_vector<T> you can hold a list of heap-allocated objects which can be even polymorphic (virtual functions), which isn't possible with simply std::vector<T>.
Unlike std::vector<T>, the objects won't be stored in subsequential memory addresses. Things like resizing the container however will be faster because the elements will keep their original memory addresses. The best bonus is, you don't need to call delete yourself: the contained objects will be destroyed when the ptr_vector goes out of scope. Example:
#include <boost/ptr_vector.hpp>
#include <iostream>
class test() {
protected:
int const i;
public:
explicit test(int i) : i(i) {}
virtual void who_am_i() const { std::cout << "I am test " << i << std::endl; }
};
class special_test : public test {
public:
explicit special_test(int i) : test(i) {}
virtual void who_am_i() const { std::cout << "I am special_test " << i << std::endl; }
};
int main() {
boost::ptr_vector<test> objs;
for (int i=0; i<50; ++i)
objs.push_back(new test(i)); // NB: constructing to heap here!
objs.push_back(new special_test(123)); // objs can also hold inherited classes
objs[13].who_am_i(); // outputs: I am test 13
objs[50].who_am_i(); // outputs: I am special_test 123
} // all created objects are automatically destroyed here