How do I delete this allocated pointer?
int (*foo)[4] = new int[100][4];
Is it just :
delete[] foo;
As you have allocated an array you have to use operator delete[]
delete []foo;
That it would be more clear you can rewrite the code snippet the following way
typedef int T[4];
T *foo = new T[100];
delete []foo;
Related
void foo(int i)
{
char* p = new char[10];
if (i)
{
p = 0;
}
delete[] p;
}
In the above code snippet, p resource was referenced to zero. Will this create a memory leak in my code?
Yes it leaks in case i != 0.
Your variable p points to some address in memory and by doing p = 0; you erase that pointer. So the instruction delete[] p; will work for a nullptr pointer and you'll not free the allocated memory.
For this type of problems we use smart pointers (unique_ptr, shared_ptr, ...) and STL containers and objects like std::string, std::vector<char>, std::list<char> and so on.
So, in your case you have to change code to something like that
{
char* p = new char[10];
if (i)
{
if (p) {
delete[] p;
p = 0;
}
}
if (p) {
delete[] p;
p = 0;
}
}
Inside your function foo, you are setting the value of the pointer p, which actually is a pointer to the beginning of your dynamic array, to 0 if i is non-zero:
if(i)
{
p = 0;
}
Therefore, when i is non-zero, p no longer points to the start of your array and the delete command will fail to deallocate the array that you create inside the function.
So yes, when i is non-zero, your function will leak memory. I wouldn't change p if I were you. Keep that unchanged until the end so that you call delete [] on it and deallocate the array.
Alternatively, consider using a std::vector instead:
std::vector<char> vec(10);
This does something equivalent except it will take care of the memory allocation/deallocation for you automatically.
I would like to have a dynamic array of pointers to pointers to Pair elements;
int m_size = 0;
Pair** ar = new Pair*[++m_size];
*ar[0] = Pair(key, data);
Here I get:
Unhandled exception at 0x013729db in lab3.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
It happened in the overloaded operator for MyString (HERE marks when the exception threw):
MyString & MyString::operator = (const MyString & refMyString){
HERE: this->m_pStr = refMyString.m_pStr;
return *this;
}
My classes (a bit simplified for our purpose):
class Pair{
MyString m_key;
Data* m_data;
}
class MyString
{
char* m_pStr;
}
And here is what I get in the debugger:
http://sdrv.ms/ZwkZ9P
http://sdrv.ms/17eoGp6
Well, as far as I can see, when I did Pair** ar = new Pair*[++m_size], a new pointer to pointer to a space for a Pair instance was created. But it is just space in memory. And when I try to operate it, I fail.
And what to do is a mystery to me. Could you help me?
You allocate an array of Pair* but :
1) You never initialize the pointers in that array
2) You dereference those uninitialized pointers (which point to who-knows-where) and overwrite the memory there.
No wonder you get a segfault since you're writing to unallocated memory.
What you (probably?) want to do is:
ar[0] = new Pair(...)
Or better yet, use a standard container (vector, list, deque, ...) instead of C arrays, that will either contain plain objects or smart pointers (unique_ptr or shared_ptr) so that you don't have to manage the memory yourself.
When creating a two dimensional array using a double pointer, you need to allocate both dimensions:
// allocates an array of 10 int* objects
int** p = new int*[10];
for(int x = 0; x < 10; ++x)
{
// Allocates an array of 3 integers
p[0] = new int[3];
}
You would need to ensure that all of the objects you are creating are deleted:
// later
for(int x = 0; x < 10; ++x)
delete [] p[x];
delete [] p;
I would suggest however, just using std::vector so you don't need to manage the memory yourself:
std::vector<std::vector<int>> p;
p.resize(10);
for(int x = 0; x < 10; ++x)
{
p[x].resize(3);
}
Consider this code:
using namespace std;
int* get()
{
unique_ptr<int> p (new int[4]);
return p.get();
}
int main(int argc, char **argv)
{
int *arr1=get();
int* arr2=get();
for(int i=0;i<4;i++)
{
arr1[i]=i;
arr2[i]=i*2;
}
for(int i=0;i<4;i++)
cout << arr1[i];
return 0;
}
arr1 and arr2 point to the same area of memory.
So they share the same values.
I don't understand why, when I call arr2=get() :
unique_ptr<int> p (new int[4]);
This object shouldn't be created again? It isn't deleted because still reachable by arr1.
How to get two arrays of different memory areas?
I am fairly sure you are playing with undefined behavior which is bad.
the data being pointed to was destroyed when the unique pointer was destroyed, the fact the values are the same, and the same slot was chosen is luck.
for pointers to array type use a vector
std::vector<int> get()
{
return std::vector<int>(4);
}
int main()
{
std::vector<int> arr1=get();
std::vector<int> arr2=get();
return 0;
}
for normal single value pointers then you can return a unique_ptr;
std::unique_ptr<int> get(){
return std::unique_ptr<int>(new int(0));
}
:::
std::unique_ptr<int> ptr=get();
There are a memory leak in such kind of usage of smart pointers. unique_ptr will use operator delete in order to free the allocated memory, but you need delete []. Also the return value of get function will be an invalid ptr because the unique_ptr will free the allocated area. If you need dynamically allocated arrays then use std::vector.
I have:
class first{
private:
int *array;
public:
first(int x){
array = new int[x][10];
}
I want to call this class by:
first class1 = new first(10);
Why it doesn't work ? How to inintialize array by size from constructor ??
Just this is enough:
first class1(10);
new is for when you're allocating a pointer.
first *class1 = new first(10);
Furthermore, you have an incompatibility here:
array = new int[x][10];
array is an int*, but new int[x][10] is a 2D array. I'm not sure which one you want.
For the 1D array:
int *array;
array = new int[x];
For the 2D array:
int (*array)[10];
array = new int[x][10];
That said, you might be better off using std::vector.
Side Note: Since you have memory allocation in the constructor, you should also implement a destructor, copy-constructor, and copy-assignment operator.
You've indicate that you want a one-dimensional array (int*) but attempted to allocate a two-dimensional array (new [x][10]).
I'll assume you need one dimension.
The C++ way to do this is with vector.
#include <vector>
class first{
private:
std::vector<int> array;
public:
explicit first(int x) : array(x) {
}
};
struct item
{
unsigned int a, b, c;
};
item* items[10];
delete items[5];
items[5] = NULL;
The above code works
But the below method is not working
int * arr1[30];
delete (arr1+5);
I am a beginner, Please tell me why I am able to delete in case of structure pointer but not in case of int
pointer
You're seemingly misunderstanding what delete is for: it's purely and simply to release memory allocated by new, not to 'delete' elements of arrays.
So you might use it like this:
int *p = new int;
//...
delete p;
When you allocate arrays, you must instead use delete[], like this:
int *q = new int[23];
//...
delete [] q;
But at no point should you try and delete something that hasn't been new'ed, or use the non-matching version of delete, e.g. delete [] p; or delete q; above.
If what you really want is some sort of 'array' from which you can remove elements, try this:
#include <vector>
struct item
{
unsigned int a, b, c;
};
int main()
{
std::vector<item> items(10);
items[5].a = 23;
items.erase(items.begin() + 5);
return 0;
}
Are you allocating heap memory anywhere? You are not doing so in the code above. You are lucky that the first delete does not crash.
When using the (arr1+5) approach, you are passing the memory address of the array slot itself at index 5, not the int* that the slot contains. To delete the int* that is contained in the slot at index 5, you have to dereference the pointer value, eg:
delete *(arr1+5);