Hi so I have something like:
int *p=new int[3];
*p=1;
p++;
*p=2;
delete [] p;
Is this the correct way to delete the array that p is pointing to?
You're calling delete on the middle of the array which is undefined behavior. In this simple case you'd just need to go back to the start of the array
delete [] (p - 1);
You should adjust your code to use indexing
p[0] = 1;
p[1] = 2;
Or just make a copy of the pointer
auto p2 = p;
*p2 = 1;
++p2;
*p2 = 2;
delete [] p;
No, you are deleteing a pointer that you did not new. You've changed the value the original pointer you newed.
The correct way to do that is:
int* p = new int[3];
p[0] = 1;
p[1] = 2;
delete[] p;
In that case you keep the original pointer to the memory you allocated.
If you really need to do arithmetic on your pointer you should save the original value so that you can pass it to delete[].
int* p = new int[3];
int* orig = p;
*p = 1;
p++;
*p = 2;
delete[] orig;
Related
int main()
{
int *dizi = new int[3];
int *ptr = new int;
*dizi = 1;
*(dizi + 1) = 2;
*(dizi + 2) = 3;
ptr = (dizi + 2);
delete ptr;
for (int i = 0; i < 2; i++)
{
cout << *(dizi + i) << endl;
}
delete[] dizi;
}
I want to return the dizi[2] value but I can't, it just crashes how can I do this, can you give me an example?
Trying to delete ptr is the same as trying to delete dizi[2] as you can read in the comment section delete must be used in an address returned by new. The behavior of your program is undefined.
You also have a memory leak, the memory allocated and assigned to ptr will be inaccessible when you reassign ptr.
If you want to assing the value of dizi + 2 to ptr you would need:
//...
int *ptr = new int;
*ptr = dizi[2]; // or *(dizi + 2);
std::cout << *ptr; // use it
delete ptr; // delete if after use
//...
If, on the ther hand, your intention is to assing dizi + 2 (or &dizi[2]) to ptr, no memory allocation is needed for ptr you can just make the assignment directly:
//...
int *ptr = dizi + 2;
std::cout << *ptr;
//...
Note that, in this case, after the array deletion, ptr becomes dangling, you can no longer use it while it's pointing to dizi + 2.
The situation is:
int main ()
{
int *p1 = new int[50];
int *p2 = p1;
...
When I want to delete my array I do:
delete[] p1;
Can I do it also with this:
delete[] p2;
?
Both pointers are pointing to the same memory, so you can use either one when you delete[]. But only do it once, deleting already deleted memory is undefined behavior. So if you do delete[] p1; then you can't do delete[] p2; as well, it's one or the other.
If not to delve into the details the definition of the delete operator looks the following way
delete expression
delete [ ] expression
As you can see it uses an expression (more precisely a cast expression). For example you could write
int *p1 = new int[50];
int *p2 = p1 + 50;
delete [] ( p2 - 50 );
(Notice that you have to enclose in parentheses expression p2 - 50.)
The expression is evaluated and its values is used as the address of the memory being deleted.
After deleting the memory you may not access it. Otherwise the bahaviour of the program will be undefined.
Since p2 points to the same block of memory that was allocated by p1 then yes, p2 can be used to erase that block of memory.
You can verify this by running the following code...
#include <iostream>
using namespace std;
int main()
{
int* p1 = new int[10];
int* p2 = nullptr;
for (int i = 0; i < 10; i++) {
p1[i] = i * i;
}
// 1st run
for (int i = 0; i < 10; i++) {
cout << p1[i] << " ";
}
cout << endl;
p2 = p1;
if (p2 != nullptr) {
delete p2;
}
// 2nd run;
for (int i = 0; i < 10; i++) {
cout << p1[i] << " ";
}
p1 = nullptr;
p2 = nullptr;
return 0;
}
The 2nd run through the p1 array shows that the content of that array was deleted by the delete p2 operation which was put in an if statement for safety.
The two pointers can be put to rest, once their use is over, by equating them to nullptr keyword.
I am basically wondering how to delete a double pointer, for example char**. This is because I ran into an access violation problem which I don't quite understand. Here is the code:
StatsManager::_statsNameList = new char*[StatsManager::MAX_STATS_COUNT*StatsManager::MAX_CHANNEL_COUNT*StatsManager::MAX_ROI_COUNT];
if(NULL != StatsManager::_statsNameList )
{
for (int i = 0; i < StatsManager::MAX_CHANNEL_COUNT; i++ )
{
for (int j = 0; j < StatsManager::MAX_ROI_COUNT; j++ )
{
for (int k = 0; k < StatsManager::MAX_STATS_COUNT; k++ )
{
char* pList = StatsManager::_statsNameList[i*area + j*StatsManager::MAX_STATS_COUNT + k];
if (NULL != pList)
{
// following line is where the exception throws
delete[] StatsManager::_statsNameList[i*area + j*StatsManager::MAX_STATS_COUNT + k];
StatsManager::_statsNameList[i*area + j*StatsManager::MAX_STATS_COUNT + k] = NULL;
}
}
}
}
}
delete[] StatsManager::_statsNameList;
StatsManager::_statsNameList = NULL;
I am very confused because for the inner loop where the exception throws, I watched the pLsit is a bad pointer, so how come the if (NULL != pList) still get passed?
And what is the correct way to delete a char**? Thanks a lot.
Usually you have to follow two points:
If you used new[] for allocation use delete[] for deallocation, and if new was used for allocation delete has to be used to free the memory;
You have to free the memory on every level it was allocated, e.g.
int **pp = new *int;
*pp = new int;
**pp = 5;
delete *pp;
delete pp;
So, delete of the same type as new has to called the same number of times, but in reverse order.
You need to use the delete or delete[] operator that matches the operator used to allocate. So new[] is followed by delete[], and new by delete.
You cannot delete a char**, it's just a pointer to a pointer to a char. It depends on the object it's actually holding. Logically, a char** would itself contain an array like new char*[x], and is itself filled with objects allocated with new char[x]. In that case you need to loop over the array and delete[] those, then delete[] the outer array.
For a pointer to an int, I can do -
int *p = new int;
*p = 10;
delete p; // Step 1: Memory Freed
p = 0; // Step 2: Pointer set to NULL
Now, if I have a pointer to an int array -
int *p = new int[10];
p[1] = 1;
p[5] = 5;
delete[] p; // Step 1: Memory freed corresponding to whole array
Now, how to achieve 'Step 2' for this case?
You don't have an array of int pointers. You just have an array of int. Since you only have one pointer, p, you can just do the same thing as you did previously:
p = 0; // or nullptr, preferably
If you did have an array of int pointers, you will probably have allocated them in a loop. In the same way, you can deallocate them and set them to 0 in a loop:
int* array[10];
for (auto& p : array) {
p = new int;
}
// Some time later...
for (auto& p : array) {
delete p;
p = 0;
}
Do consider whether you need to set your pointers to null after deleteing them.
I am new to C++ and am trying to understand the proper way to deallocated array memory. I am getting the following error when try to delete an allocated pointer array:
"pointer being freed was not allocated."
My pointer is defined as:
T * al ;
al = new T[top] ;
While my destructor for the class where the pointer al is defined in is:
for( int i = 0 ; i < current ; i++ )
delete( al+i ) ;
delete [] al ;
The destructor for the class T is:
for( int i = 0 ; i < length ; i++ )
delete( p+1 ) ;
delete [] p ;
Where p is defined as:
char *p ;
length = strlen( str ) ;
p = new char[length] ;
strcpy( p, str ) ;
How to properly allocate memory and/ or how to fix this?
Just use the delete [], not the loop in addition. delete [] will delete each element of the array.
Also, your loop in the class T destructor is trying to delete p+1 instead of p+i
To be specific, you should delete like so:
int *a = new int; // One allocated
delete a; // So delete one
int *b = new int[50]; // 50 allocated
delete[] b; // Just use delete[], don't delete every one
int **c = new int*[50]; // 50 pointers to ints
for (int i = 0; i < 50; i++)
c[i] = new int; // each c[i] points to a pointer to a new int
for (int i = 0; i < 50; i++)
delete c[i];
delete[] c;
Use delete when you use new, delete[] when you use new[].
It's actually wrong to do the following:
int *a = new int[50];
// do stuff...
for (int i = 0; i < 50; i++)
delete &a[i]; // equivalent to delete (a + i);
delete[] a;
You only do a delete[] a, never the delete (a + i).