Placement new for contiguous memory - c++

I am facing some problems for using placement new for contiguous memory.Please guide me, if there is any other way to do this.
Please refer my code.
#include <new>
//================================================
class MyClass
{
private:
int ma;
public:
MyClass():ma(-1){}
};
//===========================================
int main()
{
// I am allocating the memory for holding 10 elements of MyClass on heap
void* pMyClass = ::operator new(sizeof(MyClass)*10);
//! Note :: the address of pMyClass1 and pMyClass will now point to same
//location after calling placement new
MyClass* pMyClass1 = :: new(pMyClass)MyClass();
//! Problem with this is that,
//! i can only instantiate the constructor for the base address. That is
//! pMyClass[0].
//! If i have to instantiate it for all the other instances,
//! that is pMyClass[1] to pMyClass[9], then how to do it ?
return 0;
}

You have the beginning of the memory in pMyClass, and the stride is sizeof(MyClass). So, what you need to do is for example:
MyClass* pMyClass2 = ::new((MyClass*)pMyClass + 1)MyClass();

Try:
MyClass* pMyClass1 = :: new(pMyClass)MyClass[10];

You have to call the placement new inside a loop that iterates on the 10 contiguous chunks of memory:
int main()
{
void* pMyClass = ::operator new(sizeof(MyClass)*10);
MyClass* pMyClass1 = reinterpret_cast<MyClass*>(pMyClass);
for (size_t i=0; i<10; ++i) {
::new(pMyClass1++)MyClass();
}
// ...
}

Related

freeing the same memory with distructors

I try to free the memory correctly after the program ends, but I always encounter a problem.
In my code I want to have an array of all the numbers that I allow in my program, and have objects A and B (or more) that each one have some of the numbers that I allowed.
In the end I want to delete 'a' and 'b' only after "ints" getting out of the scope. But A and B calls their distructors to delete some of ints variables.
#define MAX_LEN 255
class IntArray
{
public:
int len;
void add(int* n) {
arr[len] = n; len++;
}
IntArray() : arr(new int* [MAX_LEN]), len(0) {}
~IntArray() {
for (int i = 0; i < len; i++)
delete arr[i];
delete[] arr;
}
private:
int** arr;
};
class Object
{
public:
void add(int* n) {
myIntArr.add(n);
}
private:
IntArray myIntArr;
};
int main(void)
{
int* a = new int(5);
int* b = new int(6);
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(a);
Object B;
B.add(b);
return 0;
}
If you want to share dynamically allocated ints between multiple objects, use std::shared_ptr<int>.
Also, rather than writing a dynamic array type yourself, use std::vector to do it (correctly) for you.
using int_ptr = std::shared_ptr<int>;
class IntArray
{
public:
void add(int_ptr n) {
arr.push_back(n);
}
private:
std::vector<int_ptr> arr
};
class Object
{
public:
void add(int_ptr n) {
myIntArr.add(n);
}
private:
IntArray myIntArr;
};
int main(void)
{
int_ptr a = std::make_shared<int>(5);
int_ptr b = std::make_shared<int>(6);
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(a);
Object B;
B.add(b);
return 0;
}
If you just want to have a copyable array of int, use std::vector<int>.
You're deleting a and b twice.
You should only delete something returned by new and exactly once.
But you add them both to IntArray ints; and then one each to Objects A and B and their destructors delete them also. Destructors are called in reverse order to it's when ints is destructed you'll be deleting them again - that's "Undefined Behaviour" but normally a catastrophic failure (crash) either immediately or later during executon.
The shortest fix is:
int* a = new int(5);
int* b = new int(6);
int *ac = new int(*a);//copy of *a
int *ab = new int(*b);//copy of *b
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(ac);
Object B;
B.add(bc);
But it's not clear what our intention is. IntArray isn't an array of int as it stands, it's an array of pointers to int (which have been allocated by new).
My 'fix' will mean if you modify a (e.g. *a=20) you won't modify the copy (ac) added to the Object A.

How to add data to an array of pointers?

I created an array of pointers.
I want to know how to prp=operly add data to my array of pointers.
I have attempted the code below, unfortunately it is giving me a memory error and I do not know why.
class dataClass {
int data;
public:
void setdata(int d) {data = d;}
int getdata() const {return data;}
};
int main() {
dataClass** ptr = new dataClass*s[5];
int num = 9;
ptr[0] -> setdata(num);
return 0;
}
You just allocate the memory for the pointers (not for the objects), so ptr[0] points to an unspecified address and you get a segfault.
You need to add something like this:
for(int i = 0; i < 5; i++) {
ptr[i] = new dataClass;
}
When using a pointer-to-pointer-to-type, you must allocate storage for the required number of pointers and then allocate storage for each class which you then assign to each pointer.
For example, using 5 pointers as you attempt in your questions, you would first need to allocate for the pointers, e.g.
#define NPTRS 5
...
dataClass** ptrs = new dataClass *[NPTRS];
Now you have storage allocated for 5 pointers to type dataClass with the address for the initial pointer assigned to ptrs (I added the plural form for clarity)
The storage for the pointers is now allocated, but each of the allocated pointers does not yet point to valid storage for dataClass, they are just pointers. Before you can use the pointers to reference an instance of the class, you must allocate storage for each each class instance and then assign the address of the new block of memory to each of your pointers, e.g.
for (int i = 0; i < NPTRS; i++) {
ptrs[i] = new dataClass;
ptrs[i]->setdata (i+1);
}
(above you allocate storage for each class instance assigning the result to ptrs[i] and then set the data value to i+1)
Putting it altogether, you could do something similar to:
#include <iostream>
#include <cstdlib>
#define NPTRS 5
class dataClass {
int data;
public:
void setdata(int d) {data = d;}
int getdata() const {return data;}
};
int main() {
dataClass** ptrs = new dataClass *[NPTRS];
for (int i = 0; i < NPTRS; i++) {
ptrs[i] = new dataClass;
ptrs[i]->setdata (i+1);
}
for (int i = 0; i < NPTRS; i++)
std::cout << "ptrs[" << i <<"]->getdata() : "
<< ptrs[i]->getdata() << '\n';
return 0;
}
(note: don't forget you are responsible for keeping track of what you allocated and calling delete to free each allocation when it is not longer needed)
Example Use/Output
$ ./bin/dblptr2class
ptrs[0]->getdata() : 1
ptrs[1]->getdata() : 2
ptrs[2]->getdata() : 3
ptrs[3]->getdata() : 4
ptrs[4]->getdata() : 5
As others have mentioned, the C++ containers like vector are for less error prone and make your job a lot easier. Still, you should know how to handle both new/delete as well as the use of the containers.
Look things over and let me know if you have further questions.
You could first create an array of objects
(constructors will be called automatically).
After that create a pointer to your pointer:
#include <stdio.h>
class dataClass {
int data;
public:
dataClass(){
printf(" new instance \n");
}
void setdata(int d) {
data = d;
printf(" setdata \n");
}
int getdata() const {return data;}
};
int main() {
dataClass* ptr = new dataClass[5];
dataClass** pptr = &ptr;
int num = 9;
pptr[0]->setdata(num);
return 0;
}
result:
new instance
new instance
new instance
new instance
new instance
setdata

C++, copy constructor confusion

say I created a custom Array class and have following constructor:
Array::Array(size_t size)
{
mySize = size;
//myData is of type int*
myData = new int[mySize]; // this stuff is allocated on a heap
}
To my knowledge, a default copy constructor in this case would be implemented like that:
Array::Array(Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
Finally, say I have following code in my main.cpp file
int main()
{
Array a(1);
Array b(a); //copy constructor is invoked
}
What I expected to be was a memory leak due to deletion of myData pointers to the free store memory, BUT I have following runtime error :
*** glibc detected *** ./main.out: double free or corruption (fasttop): 0x086ad008 ***
WHY? It seems that ~Array() somehow auto frees memory allocated on a heap - but this is very counter intuitive to me. Maybe I am missing something?
UPDATE:
class Array{
private:
size_t mySize;
int *myData;
...
UPDATE 2:
main.cpp:
#include <iostream>
#include "array.h"
int main()
{
Array a(1);
Array b(a);
}
array.h:
#ifndef ARRAY_H_
#define ARRAY_H_
#include <stddef.h>
class Array{
private:
size_t mySize;
int *myData;
public:
Array(size_t size);
~Array();
void set(int i,int val);
int get(int i);
size_t getSize();
};
#endif
array.cpp:
#include "array.h"
Array::Array(size_t size)
{
mySize = size;
myData = new int[mySize];
}
Array::~Array()
{
delete[] myData;
}
void Array::set(int i, int val)
{
if(i>=0 && i<mySize)
myData[i] = val;
}
int Array::get(int i)
{
if(i>=0 && i<mySize)
return myData[i];
else return -1;
}
size_t Array::getSize()
{
return mySize;
}
I think in your destructor you have
Array::~Array(void)
{
delete [] myData; //points to the same memory on the heap
}
The problem is double free
Example:
int main()
{
Array a(1); // here a.myData = 0x12345678
Array b(a); //copy constructor is invoked // here b.myData = 0x12345678
// pop stack (call destroy of object)
// delete b.myData
// delete a.myData already delete
}
Double free
EDIT:
For your copy contructor use const because you don't modify a.
Array::Array(const Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
Good Luck !
So... despite your claims, it turns out you do delete the array in the destructor, and the copy constructor is a shallow copy, so you get a double delete. Simple.
Array::~Array()
{
delete[] myData;
}
Since this is a dynamic array, it should own the data, therefore you are right to delete in the destructor, but you need to "deep" copy in the copy constructor and the assignment operator. See the rule of three.
Your copy is a shallow copy, so IF you have a destructor that frees memory, each object attempts to delete the same memory.
You don't have to do a shallow copy. You could write your own explicit copy constructor that copies the actual data into a newly allocated array.
I like Google's suggestion to disable copy and assignment constructors and prefer explicit CopyFrom() methods.
"double free" means that the same pointer has been given to delete[] twice. because in your destructor (presumably) it's delete[]-ed both in object a and b. practical solution: use std::vector, don’t mess with raw arrays etc. needlessly.
I think your desctructors (from array 'a' and 'b') are trying to free the same memory (double free). Maybe you should check you myData before freeing.

C++: dynamically allocating a member array of structs using non-default constructor

If I have:
struct a_struct
{
int an_int;
a_struct(int f) : an_int(f) {}
a_struct() : an_int(0) {}
};
class a_class
{
a_struct * my_structs;
a_class() {...}
};
I can do:
a_class() {my_structs = new a_struct(1)}
//or
a_class() {my_structs = new a_struct [10]}
But I cannot do:
a_class() {my_structs = new a_struct(1) [10]}
//or
a_class() {my_structs = new a_struct() [10]}
Is there any correct syntax to get this to work? Or an easy work around?
If using the STL is an option, you could use std::vector instead of a dynamic array.
I think that this will work:
std::vector<a_struct> my_structs;
my_structs.assign(10, 1);
If not, this should:
my_structs.assign(10, a_struct(1));
You could allocate a raw chunk of memory and use placement new to initialize each struct:
int number_of_structs = 10;
my_structs = (a_struct*)new unsigned char[sizeof(a_struct) * number_of_structs];
// allocate a raw chunk of memory
a_struct* p = m_structs;
for (int i=0; i<number_of_structs; i++)
{
new (p) a_struct(i);
p++;
}
//When done should add code for deallocation to help people
// to understand the full cycle of memory management.
for (auto i=0; i<number_of_structs; ++i) {
my_structs[i].~a_struct();
}
delete[] my_structs;
See also: What uses are there for "placement new"?
You could use an array of pointers to pointers. Then you can create the array that will hold pointers to a_struct(), so you can decide later which constructor to use:
class a_class {
a_struct ** my_structs;
a_class() { my_structs = new a_struct* [10]}
void foo () {
my_structs[0] = new a_struct(1);
my_structs[5] = new a_struct("some string and float constructor", 3.14);
}
};
You can't do it directly on any particular parameterized constructor. However you can do,
a_struct *my_struct[10] = {}; // create an array of pointers
for (int i = 0; i < 10; i++)
my_struct[i] = new a_struct(i); // allocate using non-default constructor
I suggest using a std::vector container instead of going through this process.

Memory allocation in C++

I am confused about the memory allocation in C++. Can anyone guide me as to where each of the variable in the below snippet is getting allocated. How can I determine what is getting allocated on stack and what gets allocated on heap. Is there any good web reference for learning this.
class Sample {
private:
int *p;
public:
Sample() {
p = new int;
}
};
int* function(void) {
int *p;
p = new int;
*p = 1;
Sample s;
return p;
}
If it's created via new, it's in the heap. If it's inside of a function, and it's not static, then it's on the stack. Otherwise, it's in global (non-stack) memory.
class Sample {
private:
int *p;
public:
Sample() {
p = new int; // p points to memory that's in the heap
}
// Any memory allocated in the constructor should be deleted in the destructor;
// so I've added a destructor for you:
~Sample() { delete p;}
// And in fact, your constructor would be safer if written like this:
// Sample() : p(new int) {}
// because then there'd be no risk of p being uninitialized when
// the destructor runs.
//
// (You should also learn about the use of shared_ptr,
// which is just a little beyond what you've asked about here.)
};
int* function(void) {
static int stat; // stat is in global memory (though not in global scope)
int *p; // The pointer itself, p, is on the stack...
p = new int; // ... but it now points to memory that's in the heap
*p = 1;
Sample s; // s is allocated on the stack
return p;
}
}
int foo; // In global memory, and available to other compilation units via extern
int main(int argc, char *argv[]) {
// Your program here...
Where ever new keyword is there it get allocated on heap.
class Sample {
private:
int *p; //allocated on stack
public:
Sample() {
p = new int; //integer gets allocated on heap
}
};
int* function(void) {
int *p; //allocated on stack
p = new int; //integer gets allocated on heap
*p = 1;
Sample s; //allocated on stack
return p;
}
Any thing with new is on heap. s of Sample s gets memory allocated on stack.
class Sample {
private:
int *p;
public:
Sample() {
p = new int; //<--allocated on the heap. Anything created with operator new is allocated on the heap.
}
};
int* function(void) {
int *p; //<-- pointer is allocated on the stack as it is a local variable
p = new int; //<-- the value pointed to by p is allocated on the heap (new operator)
*p = 1;
Sample s; //<--Allocated on the stack (local variable).
return p;
}