What happens during delete of array of pointers in this case? - c++

If i define array in the next way:
char** array=new char*[3];
and I initialize the array like that for example:
for(int i=0; i<3;i++){
array[i]=new char[5];
}
and after that, I doing:
delete[] array;
What happens during the delete?

This causes a memory leak: Only memory of array is freed, but memory reserved for cells is not freed before your program closes.
You should match each new with a delete:
for(int i=0; i<3;i++){
delete[] array[i];
}
delete[] array;
If you received the pointer from some function, you need to know its size to be able to free all the memory.
To avoid manual memory handling, you can either use vector of shared pointers (std::vector<std::shared_ptr<char>) or in this specific case, use strings (std::vector<std::string>).

Related

Problem with delete[], how to partially delete the memory?

When we learn dynamic allocation in c++, the simplest example about delete[] is :
int main()
{
size_t n = 5;
int *p = new int[n];
delete[] p;
}
In plain English delete[] is able to delete an C-like array from the heap memory which is previously allocated by the new. However, i'm getting errors for the following code.
int main()
{
size_t n = 5;
int *p = new int[n];
p++; //move the pointer to the second element of the array
delete[] p;
}
I was thinking if this could delete the same heap memory, but from the second element onwards. however, i'm getting some error which i dont understand:
Test Prep(51600,0x1000d1dc0) malloc: *** error for object 0x100537134: pointer being freed was not allocated
It's simply undefined behaviour to delete a pointer that's not allocated by new. Undefined behaviour doesn't necessarily give any errors!
You're changing the pointer to point to the next element - which isn't what new returned.
There's no way to partially delete as you wanted. You should look at containers such as std::vector which supports (and manages the allocations) such partial deletion/resizing.

Do I have to delete memory in this case?

Here is a simple program using dynamic memory.
My question is do I have to delete the memory at the and or the struct will take care of it for me?
#include <iostream>
struct Student {
int grade;
char *name;
};
void print(Student name);
int main() {
Student one;
one.grade = 34;
one.name = new char[12];
int i;
for (i = 0; i < 11; ++i) {
one.name[i] = 'a' + i;
}
one.name[i] = '\0';
print(one);
delete[] one.name;
return 0;
}
void print(Student name) {
std::cout << name.name << " has a score of " << name.grade << "\n";
}
There is a simple rule of thumb- for each call of new you should have one call of delete. In this case you should delete one.name like so : delete [] one.name.
Of course you should do that after you no longer need its value. In this case this is immediately before the return.
Memory allocated dynamically using new or malloc must be freed up when you're done with it using delete or free otherwise you'll get Memory leak.
Make difference between delete and delete[]: the first without subscript operator is used to deleted dynamic memory allocated with new for a pointer. The latter is used for deleting an array allocated dynamically.
So in your case:
one.name = new char[12]; // an array of 12 elements in the heap
delete[] one.name; // freeing up memory
char* c = new char('C'); // a single char in the heap
delete c;
Don't mix new, delete with malloc, free:
This is undefined behavior, as there's no way to reliably prove that memory behind the pointer was allocated correctly (i.e. by new for delete or new[] for delete[]). It's your job to ensure things like that don't happen. It's simple when you use right tools, namely smart pointers. Whenever you say delete, you're doing it wrong.
If you don't want to use unique/shared pointers, you could use a constructor for allocating and a destructor for automatically freeing memory.
If the raw pointer in your structure is an observing pointer, you don't have to delete the memory (of course, someone somewhere in the code must release the memory).
But, if the raw pointer is an owning pointer, you must release it.
In general, every call to new[] must have a matching call to delete[], else you leak memory.
In your code, you invoked new[], so you must invoke delete[] to properly release the memory.
In C++, you can avoid bug-prone leak-prone raw pointers, and use smart pointers or container classes (e.g. std::vector, std::string, etc.) instead.
Creating a Structure does not mean it will handle garbage collection in C++
there is no garbage collection so for every memory you allocate by using new you should use delete keyword to free up space. If you write your code in JAVA you wont have to delete as garbage collector will automatically delete unused references.
Actually the structure won't freeup or delete the memory that you have been created. if in case you want to freeup the space you can do as follows.
#include <iostream>
using namespace std;
int main()
{
char *c = new char[12];
delete[] c;
return(0);
}

Deallocate Char Pointer

I've been trying to deallocate this array of char pointers, but I'm not sure how to fully deallocate it.
Here's the code:
char* words[4];
words[0] = new char[8];
words[1] = new char[6];
words[2] = new char[10];
words[3] = new char[16];
and heres what i tried
for (int i=0;i<4;i++)
{
delete [] words[i];// this works
}
delete [] words;//this gives an error, not sure why it doesn't work.
Can somebody please explain why this isn't correct and how to fix it
thanks in advance.
Only delete what you new. You didn't new words, so don't delete it. Presumably this code is inside a function, in which case words has automatic storage duration and will be destroyed automatically when it goes out of scope.
Moreover, don't new anything you don't have to, to save yourself the hassle of deleting it correctly (which can be surprisingly difficult). Use std::vector when you want a dynamic array, and std::string when you want a dynamic string.
It is not correct because words is not itself dynamically allocated like the pointers it contains.
words is on stack, words[i] is on heap. As a general principle you need a delete[] for each new[]. You have 4 new and you need 4 delete.
char *words[4] // on stack, doesn't need deallocation
char **words = new char*[4]; // on heap, would need deallocation too

array of questions on pointers, double pointers, malloc, realloc and new (to set the record straight)

I'm catching up on pointers. I wrote down a few lines of code to test the different ways I could dynamically allocate a 2d array (posted at the bottom)
My questions are the following:
Should I use malloc in c++, or new? If I use new, can I still use realloc?
When should I use realloc? What are the implications of using it in terms of performance and bugs?
Out of the examples bellow, which objectNew version should I use? If the answer depends on the application, what are does it depend on?
Many thanks,
Matt
#include <stdio.h>
#include <stdlib.h>
struct myObject
{
int data;
myObject(int i)
{
data = i;
}
myObject()
{
data = 0;
}
};
int main(){
int r = 7;
int c = 6;
printf("Objects using NEW===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject*** objectNew = new myObject** [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew[i] = new myObject* [c];
for(int j=0;j<c;j++){
objectNew[i][j] = new myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew[%2d][%2d]=%02d\n",i,j,objectNew[i][j]->data);
}
}
delete objectNew;
printf("Objects using NEW version 2===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject** objectNew2 = new myObject* [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew2[i] = new myObject [c];
for(int j=0;j<c;j++){
objectNew2[i][j] = myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew2[%2d][%2d]=%02d\n",i,j,objectNew2[i][j].data);
}
}
delete objectNew2;
printf("Objects using MALLOC===============================\n");
//notice the double pointer being allocated double pointers the size of pointers to myObject
myObject** objectMalloc =(myObject**) malloc(sizeof(myObject*)*r);
for(int i=0;i<r;i++)
{
//now we are assigning array of pointers the size of myObject to each double pointer
objectMalloc[i] = (myObject*) malloc(sizeof(myObject)*c);
for(int j=0;j<c;j++){
objectMalloc[i][j] = myObject(10*i+j);
//notice that we access data without dereferencing (.)
printf("objectMalloc[%2d][%2d]=%02d\n",i,j,objectMalloc[i][j].data);
}
}
free((void*) objectMalloc);
//same as Malloc
printf("Objects using CALLOC===============================\n");
myObject** objectCalloc = (myObject**) calloc(r,sizeof(myObject*));
for(int i=0;i<r;i++)
{
objectCalloc[i] = (myObject*) calloc(c,sizeof(myObject));
for(int j=0;j<c;j++){
objectCalloc[i][j] = myObject(10*i+j);
printf("objectCalloc[%2d][%2d]=%02d\n",i,j,objectCalloc[i][j].data);
}
}
free((void*) objectCalloc);
printf("Int using NEW===============================\n");
//int is not an object
int** intNew = new int* [r];
for(int i=0;i<r;i++)
{
intNew[i] = new int[c];
for(int j=0;j<c;j++){
intNew[i][j] = 10*i+j;
printf("intNew[%2d][%2d]=%02d\n",i,j,intNew[i][j]);
}
}
delete intNew;
printf("Int using malloc===============================\n");
int** intMalloc =(int**) malloc(sizeof(int*)*r);
for(int i=0;i<r;i++)
{
intMalloc[i] =(int*) malloc(sizeof(int)*c);
for(int j=0;j<c;j++){
intMalloc[i][j] = 10*i+j;
printf("intMalloc[%2d][%2d]=%02d\n",i,j,intMalloc[i][j]);
}
}
free((void*) intMalloc);
getchar();
return 0;
}
new and new[] are constructor aware, the C memory allocation functions are not.
Similarly, delete and delete [] are destructor aware, whereas free isn't.
realloc does not work with memory allocated with new, there is no standards defined analog to the realloc function with C++ memory management functions.
Do not mix new and delete with malloc/calloc/realloc and free (i.e. don't free any memory allocated with new, don't delete any memory allocated with malloc)
If you are doing new [], you most likely should be using an std::vector, which encapsulates all that memory management for you.
If you are using memory allocated raw pointers, you might be better served using smart/semi-smart pointers like boost::shared_ptr or boost::scoped_ptr or std::auto_ptr, depending on your needs.
Thanks to David Thornley for bringing this up:
Never mix scalar new and delete with their array forms, i.e. don't delete[] memory allocated with new, and don't delete memory allocated with new[]. Undefined behavior all around.
In your example, you SHOULD use new and new[] if you must, because as I said, they are constructor aware, and your class is not a POD data type since it has a constructor.
Please see the C++ FAQ for more information:
C++ FAQ Freestore Management
1) Should I use malloc in c++, or new?
If I use new, can I still use realloc?
Use new. And never use realloc with new.
When should I use realloc? What are
the implications of using it in terms
of performance and bugs?
Instead of using realloc, I usually implement my own memory-pool, from which I reallocate memory when I need it. This also improves performance.
Should I use malloc in c++, or new? If
I use new, can I still use realloc?
You can use malloc in C++; however, it is strongly discouraged in most circumstances. Additionally, if you call malloc, calloc, realloc, etc., you need to use free to deallocate the memory when done.
If you use new to allocate memory, you must use delete to deallocate it.
The C-allocation routines do not have type safety. new does.
If you want to write C++ (!!) programs don't use malloc, realloc, free. It is just not C++ functions.
And there is no necessity to use new is your cases (I'm talking about the example).
You should use vector or some other containter.
In general, you should try to avoid doing your own memory allocation in C++. Most (not all) arrays can be done with std::vector better than you're going to do your own, particularly since you are making a mistake here.
You allocate, say, intNew and intNew[i]. Then you delete [] intNew; (the brackets are necessary here, leaving them off is an error), without delete []ing any of the intNew[i]. The one-dimensional arrays you allocated are now memory leaks, and cannot possibly be freed because you've lost all references to them. Neither C nor C++ normally come with a garbage collector.
The C memory allocation functions deal with memory only. They aren't type-safe, and don't call constructors or destructors. They can be used with data types that require neither, but you do have to make sure they do neither. (It is possible to malloc memory and use placement new to create objects there, but that's more advanced.)
The C++ memory allocation functions deal with memory and objects. They are type-safe, mostly, and do call constructors and destructors. Not all objects can be moved safely, so there is no equivalent of malloc. The tricky part is that you have to match new with delete, and new[] with delete[]. You have this error in your code: delete intNew; should be delete [] intNew;.

delete[] and memory leaks

I am wondering about the delete[] operator in C++. (I am using Visual Studio 2005).
I have an unmanaged DLL that is being called by a managed DLL. When I close this program after performing a few tasks while debugging, I am getting many (thousands?) of memory leaks, mostly 24 bytes - 44 bytes in size.. I suspect it might be due to a certain unmanaged DLL I have.
Anyway, from what I understand, if I have the following code:
char* pointer = new char[500]
/* some operations... */
delete[] pointer;
Then all the memory for it is freed up correctly, am I right?
What happens when I have the following code:
char* pointer = new char[500];
char* pointerIt = pointer;
/* some code perhaps to iterate over the whole memory block, like so */
for (int i = 0; i < 250; i++){ // only iterate halfway
*pointerIt = 0;
pointerIt++;
}
delete[] pointer;
The memory pointed to by pointer is deleted right? So it means that pointerIt is now not pointing to valid memory.. But that's ok because I can set both pointers to NULL, right?
Anyway, what happens now if I do this:
char* pointerFirstPosition = new char[500];
char* pointerIt = pointerFirstPosition;
for (int i = 0; i < 250; i++){ // only iterate halfway
*pointerIt = 0;
pointerIt++;
}
delete[] pointerIt; // delete the pointer iterator...
Will this code delete the memory block pointed to by pointerIt up to pointerIt +500? or will it delete the memory block pointed to by pointerFirstPos to pointerFirstPos +500?
Could this result in a memory leak?
Sorry for the long winded message, I'm trying to get my message across clearly.
Thanks,
kreb
First question set:
char* pointer = new char[500]
/* some operations... */
delete[] pointer;
Then all the memory for it is freed up
correctly, am I right?
right.
Second question set:
char* pointer = new char[500];
char* pointerIt = pointer;
/* some code perhaps to iterate over the whole memory block, like so */
for (int i = 0; i < 250; i++){ // only iterate halfway
*pointerIt = 0;
pointerIt++;
}
delete[] pointer;
The memory pointed to by pointer is
deleted right? So it means that
pointerIt is now not pointing to valid
memory.. But that's ok because I can
set both pointers to NULL, right?
The memory pointer holds an address to is fully delted yes. Both pointer and pointerIt hold an address to invalid memory. Each pointer is simply a variable, and every variable is independent. So both store their own address independent of each other. The dereference operator * will simply give you the variable at that address. The variable at that address is a different variable than the pointer variable.
Third question set:
You should be deleting only the address that was allocated, the whole array. You'll have undefined results if you try to delete a partial array. Could it result in a memory leak? Possibly, could it result in a crash? Possibly, could it result in ....? Possibly.
So only delete what you allocate. If you allocate an array then you delete with delete[] if you delete a type that is not an array you delete with delete.
Here is an eample of something that is fine just for clarity:
char* pointer = new char[500];
char* pointerIt = pointer;
//This is fine because you are deleting the same address:
delete[] pointerIt;
//The memory that both variables point to is freed, do not try to free again
check out boost::shared_ptr or boost::scoped_ptr and NEVER worry about this again.
This gives you a static & reference counted way to manage your memory.
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm