I have created objects by using new, but then have dereferenced them before adding them to a vector. Despite trawling the internet I cannot work out how I can call delete on these items. I want to do this just using standard C++ and STL I don't want (e.g.) to use Boost libraries.
As you can see a, b and c lose scope and I am left with what I presume to be copies in the vector. How can I go about deleting these. I don't want to store pointers in the array as I will need to pass an API function an array of doubles.
Please someone - how do I delete these objects?
#include <iostream>
#include <vector>
using namespace std;
vector<double> vectorDouble;
void createObjects();
void createObjects() {
double* a=new double(13);
double* b=new double(14);
double* c=new double(15);
//a,b and c are not contiguous memory blocks
cout << "memory location of a: " << a << endl;
cout << "memory location of b: " << b << endl;
cout << "memory location of c: " << c << endl;
vectorDouble.push_back(*a);
vectorDouble.push_back(*b);
vectorDouble.push_back(*c);
}
int main() {
createObjects();
//the memory addresses are contiguous 8 byte chunks
cout << "vector memory at 0: " << &(vectorDouble[0]) << endl;
cout << "vector memory at 1: " << &(vectorDouble[1]) << endl;
cout << "vector memory at 2: " << &(vectorDouble[2]) << endl;
//get pointer to the 2nd element
double *P=&(vectorDouble[1]);
//dereference and look inside - two memory locations both contain the value 14
cout << "vector Pointer P ["<< P <<"] contains " << *P <<endl;
//Which should I call delete on? I have lost reference to the original pointers.
//How should I call delete on the vector?
cout << "deleting pointer that references 2nd vector element" << endl;
delete P; //********* CRASH **********
cout << "Done deleting" << endl;
}
The objects you need to delete are not in the vector, because your vector elements are not created with new. You are just passing the copy of the malloc'd doubles, not the actual allocated double to the vector, when you use the dereference operator in the push_back.
You are actually just leaking them - your code would run fine without allocating doubles:
void createObjects() {
vectorDouble.push_back(13);
vectorDouble.push_back(14);
vectorDouble.push_back(15);
}
As everyone points out, there is no reason whatsoever to invoke new in your program:
void createObjects() {
vectorDouble.push_back(13);
vectorDouble.push_back(14);
vectorDouble.push_back(15);
}
Suppose, however, that you do have some reason to call new. (I can't imagine what it might be, but let's assume you are a genius). Here is how you would do that:
void createObjects() {
double* a=new double(13);
double* b=new double(14);
double* c=new double(15);
//a,b and c are not contiguous memory blocks
cout << "memory location of a: " << a << endl;
cout << "memory location of b: " << b << endl;
cout << "memory location of c: " << c << endl;
vectorDouble.push_back(*a);
vectorDouble.push_back(*b);
vectorDouble.push_back(*c);
delete a;
delete b;
delete c;
}
You see, the push_back doesn't put a copy of your pointer in the vector, it puts a copy of your object in the vector. Once you've made the copy of your object, then your object's memory serves no continuing purpose, and can be destroyed.
The function createObjects is not putting the allocated values into the vector; it is putting in the values and then leaking the memory that a, b, and c pointed to. The call:
vectorDouble.push_back(*a);
stores the value pointed to by a in the vector (*a dereferences the pointer, which you probably already know). Once that function returns, the pointers are lost. You cannot retrieve them from the vector. You would either need to make a vector of pointers to doubles or (more likely) don't even allocate values; just store the doubles.
I think I've got the problem, on:
vectorDouble.push_back(*a);
vectorDouble.push_back(*b);
vectorDouble.push_back(*c);
You are passing a, b and c as values so the array don't really contains the variables you have created (that's why they now have different memory address, they are a copy of the content of your variables!). Then you can delete the variables inside the method, don't use pointers inside the method or use an double* vector.
Your leak is in createObjects(), because std::vector<>::push_back() makes a copy of its argument. You should delete the pointer before the end of scope of createObjects().
That said, I don't see why you use dynamic allocation to begin with. If you can avoid that please do (and you can, with a smart pointer like std::unique_ptr<>, or better yet with plain old doubles).
Related
What is the memory allocated to char *ptr:
#include <iostream>
using namespace std;
class A
{
private:
int count;
char *ptr;
public :
void print()
{
cout << "Addr " << &ptr << endl;
cout << "Addr " << *ptr << endl;
}
};
int main()
{
A obj;
obj.print();
A *obj1 = new A(obj);
obj1->print();
cin.get();
return 0;
}
I am using compiler provided copy constructor. I am interested in understanding how much memory will me allocated to the *ptr.
How much memory? Well, none at all. All you have is an unitialised char*, itself occupying sizeof(char*) bytes of memory. You will need to allocate memory yourself (perhaps with a new) and assign that memory to ptr. Don't forget to free the memory (perhaps with a delete) once you're done with it; typically done in a destructor.
Better still, use std::string which takes care of all the memory for you.
(P.S. technically the line cout << "Addr " << *ptr << endl; gives you undefined behaviour as you are dereferencing an unitialised pointer).
The char * alone will take up 4 bytes on a 32-bit machine, 8 bytes on a 64-bit machine. When you assign a memory (allocated using new perhaps) to ptr only the address of the memory is stored in ptr and the actual memory is allocated on the heap.
lI'm running a C++ program on a 64-bit machine. The program dynamically creates objects from different classes. When I print out the value of the pointers (not dereferencing) to those objects using cout, the address of some objects is 48-bits while the address of other objects is 28-bits! I have read that some processors currently only support 48-bits, but why then do I get an output of 28-bits in some cases? What does that even mean?!
Edit:
This is part of a big project. So, I won't be able to post the exact code. But here is what is basically happening. I do realize that the objects need to be deleted to avoid memory leaks.
ClassA *pA = new ClassA();
ClassB *pB = new ClassB();
cout << "Address of ClassA object = " << pA << " , Address of ClassB object = " << pB << endl;
pA = new ClassA();
pB = new ClassB();
cout << "Address of ClassA object = " << pA << " , Address of ClassB object = " << pB << endl;
Now the output that I get is the following:
Address of ClassA object = 0x7fcda0001150 , Address of ClassB object = 0x19f1160
Address of ClassA object = 0x26c77c0 , Address of ClassB object = 0x1aba400
I guess, you just observed that objects are allocated in different memory regions:
Objects with static linkage are generally located in the data segment next to the segment with the program code and typically have relatively small values.
Objects on the stack are typically located at the far end of the memory with the stack normally growing downwards. They have, thus, normally fairly large values.
Objects allocated on the heap are typically somewhere between the data segment and the stack. Depending on how the memory allocation decides to allocate memory, the value are likely to start small, i.e., just above the data segment or fairly large, i.e., just below the stack.
How systems really lay out their memory is entirely up to the system, however. Some systems may have entirely different memory layouts, have stacks growing upwards, etc. Here is a simple program demonstrating this effect:
#include <iostream>
int main()
{
static int a(0);
static int const b(0);
int c(0);
int* d(new int(0));
std::cout << "a=" << &a << '\n'
<< "b=" << &b << '\n'
<< "c=" << &c << '\n'
<< "d=" << d << '\n';
delete d;
}
On my system, this program prints
a=0x103504064
b=0x103503f7c
c=0x7fff5c6fca8c
d=0x7f92204000e0
I guess, something like this difference led you to the assumption that pointers are different but it is just that the value formatted require a different number of digits: all int*s used will have the same size.
I want to put both 1-dimensional array pointer and 2-dimensional array pointer in a union, so I can access data either way. In the following program I would like to see the value 9 is printed out by both ways.
#include <iostream>
class A {
public:
union {
int** array2D;
int* array1D;
};
A() {
array2D = new int*[1];
array2D[0] = new int[1];
}
};
int main() {
A a;
a.array2D[0][0] = 9;
cout << a.array2D[0][0] << endl;
cout << a.array1D[0] << endl;
cout << a.array2D << endl;
cout << a.array1D << endl;
}
The actual output:
9
146989080
0x8c2e008 //Pointer address of array2D
0x8c2e008 //Pointer address of array1D
The addresses are identical and by definition multidimensional arrays are stored in the same way as are one-dimensional arrays. I wonder why the two couts print out different results? What did I miss?
EDIT:
Thanks to the answers below, I can see what I missed.
The fix for accessing data from array1D is:
cout << *( (int*) a.array1D[0]) << endl;
First of all you are invoking undefined-behavior.
the standard says that you are only allowed to read from the member of a union that you last wrote t, reading array2D and array1D interchangeably is therefore not allowed (even though it often works in practice it is not recommended).
Second; using array1D you are trying to dereference and read the value at the address currently (supposedly because of UB) having been allocated for a new int*[1], the value of array2D[0][0] is located one further step down the path.
To access the value you are expecting from a.array1D you will need something as the below (not recommended)
**reinterpret_cast<int**> (a.array1D);
When you allocate multidimensional array using new, the way you do it, you are actually allocating a number of arrays.
The first one is an array of pointers to array. Thus your a.array1D[0] contains actually pointer to pointer to array, and you are printing a value of the pointer.
I am pretty sure if you will do the following:
cout << (int*)a.array1D[0] << endl;
you will get the same as:
cout << a.array2D[0] << endl;
When you print out the value of a.array2D is points to the beginning of the array. Since you are using a union both array1D and array2D occupy the same space and will contain the same value.
When you access the pointer value in a.array1D[0] you are telling it to get the first element of array1D. Because you are using a union this also points to the first element of array2D which happens to be a pointer.
#include <iostream>
int main()
{
int anything[] = {5};
int *something = new int;
*something = 5;
std::cout << &anything << "==" << &anything[0] << "==" << anything << std::endl;
std::cout << &something << "!=" << &something[0] << "==" << something << std::endl;
}
Why is the memory address in &something different from &something[0] and something? Although it is a dynamic allocation, I don't understand why the memory address is different. I tried it with more than one value; it's the same thing. Here I used one value for both for simplicity.
&something is the memory address of the pointer itself (hey, it needs to store that value somewhere!), while &something[0] is the address of the actual memory that is storing your stuff.
something is a pointer. &something is the address of that pointer. &something[0] is the address of the first element pointed to by the pointer, which is completely different from the address of the pointer. something is the value of the pointer, which is also the address of the element that is pointed to.
I'm sure this topic has been covered many times before, I hope I did it justice.
Correction:
I messed up with the concept of pointer address and the address the pointer points to, so the following code has been modified. And now it prints out what I want, variable a, c, i, j, k, p are on the stack, and variable b,d are on the heap. Static and global variables are on another segment. Thanks a lot for all of you!
Well, I know that these two concepts are deeply discussed...but I still have questions for the following code:
#include <iostream>
using namespace std;
class A {
};
int N = 10;
void f(int p) {
int j = 1;
float k = 2.0;
A c;
A* d = new A();
static int l = 23;
static int m = 24;
cout << "&c: " << &c << endl;
cout << "&d: " << d << endl;
cout << "&j: " << &j << endl;
cout << "&k: " << &k << endl;
cout << "&l: " << &l << endl;
cout << "&m: " << &m << endl;
cout << "&p: " << &p << endl;
}
int main() {
int i = 0;
A* a;
A* b = new A();
cout << "&a: " << &a << endl;
cout << "&b: " << b << endl;
cout << "&i: " << &i << endl;
cout << "&N: " << &N << endl;
f(10);
return 0;
}
My result is:
&a: 0x28ff20
&b: 0x7c2990
&i: 0x28ff1c
&N: 0x443000
&c: 0x28fef3
&d: 0x7c0f00
&j: 0x28feec
&k: 0x28fee8
&l: 0x443004
&m: 0x443008
&p: 0x28ff00
This is pretty interesting, coz except the global variable N, and two static variables in function f, which are l and m, the addresses of all the other variables seem to be together. (Note: The code and the results have been modified and not corresponding to what is said here.)
I've searched a lot about stack and heap. The common sense is that, if an object is created by "new", then it is on the heap. And local variables (such as j and k in the above sample) are on stack. But it seems not to be the case in my example. Does it depend on different compilers, or my understanding is wrong?
Thanks a lot for all of you.
Your understanding is wrong. For example, b is a pointer - if you want the address of the object created by new, you need to print out b, not &b. b is a local variable, so it itself (found at &b) is on the stack.
For your example, N, l, and m are presumably somewhere in your executable's data section. As you can see, they have similar addresses. Every other variable you are printing out is on the stack - their addresses are likewise similar to one another. Some of them are pointers pointing to objects allocated from the heap, but none of your printouts would show that.
Your understanding is correct.
local variables are allocated on the stack.
dynamically allocated objects are allocated on the heap.
Though you are taking the address of the local variable consistently in your example.
Example: print out d not the address of d. As d is a local variable (so the address is similar to c) but it is a pointer variable that points at a dynamically allocated object (that is on the heap).
How the compiler implements the stack and heap though will vary.
In modern OS the stack and heap may even share the same area (ie you can implement the stack by allocating chunks in the heap).
If you want to print the address of whatever d points to (in this case it points to an object on the heap), do
cout << "d: " << d << endl;
That will print the value of the pointer, and the value of a pointer is the address of the object it points to.
Your code had
cout << "&d: " << &d << endl;
This prints the address of d , as you defined d inside main, it'll be on the stack, you're printing the address of your pointer. There's the pointer itself, and the object it points to, they're 2 seperate things, with seperate addresses.
The only ones that are not 'together' in your example are l, m and N. They are two statics and one global, therefore they are not allocated on the stack for sure. They aren't from a heap neither, most likely, they are from a .data segment of your module. The only one from a heap should be the address b points to, but you're printing the address of b itself, not what it points to.
The distinction between the two forms, from a pure C++ perspective, is only to do with how lifetime of objects are managed.
From here, good read
Static variables are in the data segment. Also you mix the address of a pointer and it value. For example a:
a is a local variable of type A* on the stack. &a also gives the address where a actaully resieds (on the stack). The value of a is an address of a heap object of type A;
You can't depend on various compilers doing things the same way. For almost every bit of code you will write the distinction between stack and heap are meaningless. Don't worry about it.
One may not safely assume anything about the relative addresses of things in the stack relative to those on the heap nor, for that matter, the relative addresses of any pointers that are not all derived from the same array or allocated (via malloc, calloc, etc.) block. I'm not even sure pointers are required to be rankable.