Deleting part of array not allowed, why? [duplicate] - c++

This question already has answers here:
Can I delete[] a pointer that points into an allocated array, but not to the start of it?
(7 answers)
Why can't I delete pointer alone from an array of objects?
(4 answers)
Closed 5 years ago.
Consider, below program which gives runtime error. Point of this question is to understand memory view and management.
#include<iostream>
using namespace std;
int main(void) {
char* arr = new char[10];
char* ptr = NULL;
for(int i = 0; i < 10; i++) {
arr[i] = 'a';
}
cout << arr;
ptr = &arr[5];
delete ptr;
cout << arr;
return 0;
}

new allocates a block of memory. You can free that memory using delete, but you must pass the same address that was returned by new. That's how it works. You can't pass arbitrary addresses to delete.
Another option is to use malloc() and free(). These are older function but then you can also use realloc() to resize the memory. Then, if you want to delete part of the array, you can resize it to be smaller. BUT... you must still copy any data as needed to correctly form the resized array. That is not automatic.

Related

delete[] operator in C++ not working as it should [duplicate]

This question already has answers here:
What happens to the pointer itself after delete? [duplicate]
(3 answers)
Why doesn't delete set the pointer to NULL?
(12 answers)
Closed 2 years ago.
Please have a look at this below code::
#include<iostream>
using namespace std;
int main()
{
int *ptr;
ptr = new int[100000];
cout<<"\n\n address = "<<ptr;
for(long int i=0;i<100000;i++)
*(ptr+i) = i+1;
delete []ptr;
cout<<"\n\n address = "<<ptr;
ptr = new int[5];
cout<<"\n\n address = "<<ptr;
return 0;
}
OUTPUT is:
address = 0xd42490
address = 0xd42490
address = 0xe919d0
Why,After delete []ptr; it is still pointing to its previous location(See the 2nd output).
delete[] is working just as it should. It ensures that destructors are called for the members of the array and marks the memory (internally) as available for re-use.
There's nothing in the C++ standard that says it has to zero the memory or return the memory to the OS or clear the variable holding the address you passed to it, etc.
Once you delete something, you know destructors have run and you also know that you are no longer allowed to look at (access) that memory. If you do anyway, there's no guarantee what you'll get (except UB).
A pointer is just like a cardboard sign saying "there's something over there". When you use delete on the pointer it destroys what's "over there", but it doesn't re-write the sign itself (the pointer), so the pointer still points to the same memory location it always did, but accessing that memory location is now forbidden.
delete [] has destroyed the array created dynamically at address ptr, but has not deleted the pointer itself.
A ptr = nullptr; command would perform that job, by indicating that ptr now points to nothing.

Is it safe to use the "realloc" after the "new" operator in C++? [duplicate]

This question already has answers here:
Is it safe to realloc memory allocated with new?
(9 answers)
Closed 4 years ago.
As far as I know, there is no exact alternative for the realloc of C in C++ like the new for malloc. However, when I use the realloc in C++ to alter the memory allocated by the new operator, it works fine.
Is it safe to use those two (new and realloc) like I do in the codes below or it can lead to some problems?
#include <iostream>
#include <cstdlib>
int main()
{
int size = 5;
int * arr = new int[size]{ 1,3,5,7,9 };
for (int i = 0; i < size; i++)
std::cout << *(arr + i) << (i < size - 1 ? ' ' : '\n');
size++;
arr = (int*)realloc(arr, size * sizeof(int));
*(arr + size - 1) = 11;
for (int i = 0; i < size; i++)
std::cout << *(arr + i) << (i < size - 1 ? ' ' : '\n');
delete[] arr;
//free(arr);
std::cin.get();
return 0;
}
Also, which operator should I use in such a case to free the memory: delete[] of free()?
No, the behaviour is undefined. You can only call delete[] on a pointer that you've obtained from a call to new[].
Using std::vector would cause all these memory issues to fall away.
It is not safe. new should only be matched by delete or delete[] - using it with realloc is dangerous and could lead to security risks.
Also, why are you using new and delete in the first place? Use containers like std::vector or smart pointers such as std::unique_ptr if you really want to manage memory yourself.
Don't mix c memory functions with c++ memory functions or you're gonna have a bad time.
See this:
What is C++ version of realloc(), to allocate the new buffer and copy the contents from the old one?

Access to infinite array elements? [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 6 years ago.
I try to understand pointers. Question is: should'nt I get a segmentation fault when compiling the second for loop? If no why not? I could not prevent any access to elements which are outside of y[0][dim].
int main(){
int dim = 3;
int ordnung = 2;
double** y = new double*[ordnung];
for(int i = 0; i<ordnung; i++){
y[i] = new double[dim];
}
for(int i = 0; i<=100; i++){
cout << y[0][i] << endl;
}
delete[] y;
return 0;
}
The output is also confusing me:
0
0
0
1.63042e-332
0
0
0
6.520933e-319
and ongoing zeros. What does that mean?
When you allocate memory using new[], it doesn't initialize the memory in any specific way. Its content is indeterminate and accessing it, even for reading, leads to undefined behavior.
You also go out of bounds of the allocated memory which also leads undefined behavior. C++ have no built-in bounds-checking.
And then you don't free all the memory you allocate. For each new there should be a matching delete, and for every new[] a matching delete[].
Lastly a few notes: First of all if you ever think you need a dynamic array, then your next thought should be std::vector.
And about the memory being uninitialized when using new or new[], that of course depends on what you allocate. If you allocate an object (or an array of objects) with a constructor, that will of course cause the constructor to be called. The constructor may, or may not, initialize the object.

C++ pointer array is still accessible after delete[] is called [duplicate]

This question already has answers here:
c++ delete pointer issue, can still access data [closed]
(6 answers)
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
In the following code, delete[] is called once to free up the memory allocated by new. However, the array elements is still accessible after delete[] is called. I called delete[] twice to confirm that I am getting a double free or corruption error, which I am getting, which means the memory is freed. If the memory is freed, how am I able to access the array elements? Could this be a security issue which might be exploited, if I am reading something like a password into the heap?
int *foo;
foo = new int[100];
for (int i = 0; i < 100; ++i) {
foo[i] = i+1;
}
cout << foo[90] << endl;
delete[] foo;
cout << foo[90] << endl;
gives the following output
91
91
and
int *foo;
foo = new int[100];
for (int i = 0; i < 100; ++i) {
foo[i] = i+1;
}
cout << foo[90] << endl;
delete[] foo;
delete[] foo;
cout << foo[90] << endl;
gives
*** Error in./a.out': double free or corruption (top): 0x000000000168d010 ***`
The memory is free, which means it isn't attributed anymore, but the compiler's not going to take the extra effort to wipe it back to 0 everytime something's deleted.
It's also not going to take the effort to check that the memory is properly allocated before you access it - it'd reduce performance, and it assumes you don't do so. (Although tools like valgrind or debuggers can detect those wrong calls)
So it just changes the range of the memory as 'unassigned' internally, which means another call to new can use that same memory range. Then whatever data in that memory would be overwritten, and foo[90] won't return the same thing anymore.

How to delete objects from vector of pointers to object? [duplicate]

This question already has answers here:
Calling delete on variable allocated on the stack
(12 answers)
Closed 9 years ago.
I am trying to understand how to delete a vector of pointers, and the pointed objects, in memory. I have started with a simple example, found in another thread, but I get "pointer being freed was not allocated" error.
What I am doing wrong?
#include <vector>
#include <algorithm>
#include <iostream>
int main(){
std::vector <int *> vec;
int a = 2;
int * b = &a;
int c = 3;
int * d = &c;
vec.push_back(b);
vec.push_back(d);
for (int i = 0; i < vec.size(); i++) {
delete vec[i];
}
vec.clear();
}
Only call delete on variables that were created with new
Check this link:
Calling delete on variable allocated on the stack
You're deallocating memory that was allocated on the stack with automatic storage. That's why you're getting errors.
Only delete things you allocated with new. RAII will take care of the rest.
When you do
int a = 2;
You are allocating a int on stack and anything on stack does not need to delete, it will be freed automatically once we left the scope it is declared. Therefore in your code, you are trying to free the same thing twice.
Whilst if you do
int* a = new int(2);
You will then allocate a int on heap, where data will not be deleted unless you explicitly call delete.
The bottom line is, new and delete should always be written in pairs.