Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I have a class that includes a std::uint_8 pointer and the destructor should be called to delete the allocated memory. The issue I'm having is that a complier error occurs and states that the memory was not allocated, but I know I allocated it in my default constructor.
Here's my default constructor:
BigInteger::BigInteger() {
unsigned char aArray [4];
aArray[0] = 0;
m_number = new unsigned char[4]
m_number = aArray;
m_digitCount = 0;
m_sizeReserved = 4;
}
and here's my destructor:
BigInteger::~BigInteger() {
delete [] m_number;
}
unsigned char aArray [4] here you create an array of 4 elements on the stack. These will go out of scope once the constructor has finished.
m_number = new unsigned char[4] now you create 4 elements on the heap. You allocate the memory and you'll be in charge of cleaning it up. Not an issue, you do so in the destructor.
m_number = aArray; now you change what m_number is pointing to, effectively losing a pointer to the memory you allocated. Now you have a leak.
Any use of m_number outside of this constructor is now undefined behaviour, because you're accessing memory you no longer own.
delete [] m_number; now you're deleting memory you don't own. UB.
Don't reassign m_number and you won't have these issues. Better yet, use std::vector and watch as these manual memory management problems melt away.
That line
m_number = aArray;
assigns a local variable's address to m_number.
That address cannot be used in conjunction with delete [] m_number;, the memory address allocated with new unsigned char[4] is overridden and lost after that assignment.
You have a classical scenario of a memory leak. In essence what you are doing is the following:
Allocate memory (m_number = new unsigned char[4])
Override the pointer that points to that allocated memory (m_number = aArray)
Never delete the allocated memory as you no longer know where it is - you have lost the pointer to it (it got overwritten)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I know if I create a pointer in the header file, I should always delete it when the destructor is being called, but what about if I create a pointer inside of a function. I know basic variables get destroyed at the end of the block, is it the same for pointers?
For example:
Class::Function()
{
int i = 3; // This gets destroyed after the function ends
int* j = 5; // What about this? Do I have to delete it somewhere to keep from a leak?
}
If I initialize j inside of the constructor, I would say delete j; to prevent leaks, etc. Is there something I should do in this case?
Assigning int value to pointer
int* j = 5;
is illegal because you are storing int to int*. Anyway you can cast it
int* j = reinterpret_cast<int*>( 5 );
but dereferencing this pointer would lead to undefined behavior, since you dont know where does that pointer point.
You should init pointers like that
int* j = nullptr;
Since c++11 you cant create instance of nullptr_t and assign it.
nullptr_t initPointer;
int* j = initPointer;
If you dont use new operator to assign memory to pointer, you can't delete this pointer, it would lead to undefined behavior. Otherwise if you use new you need matching delete or you would get memory leak. If you want to check your program have memory leaks, check this thread and choose one tool. I can recommend valgrind.
Every call to new needs a matching call to delete. If you have more new's than delete's, you get memory leaks. If the opposite, you get double deletes. In your case, if you never called new, then there's no need for delete!
There are tools out there to help match your new's and deletes. My personal favorite is cppcheck. It's super quick and easy to use, and it runs on the c++ source code! It generally does a good job at catching unmatched new and delete calls.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
dynamic memory allocation by pointers
what is the link between pointers and dynamic memory allocation . why do we use pointers for
dynamic memory allocation . whenever we use new operator we use only pointer variables why?
can anyone explain with an example
According to your question to start with you need not programming but real life example.
Imagine you live in your ordinary flat, it has its own address and on the door you can see big sign "Robin Mandela". It's like static memory allocation. On the start of your program you have some room in memory and a name associated with it. On every vacation you fly to other country where you rent a room in a hotel. You can live one year in one room, another year in another room and even change room during your vacation. You may even not really be interested in what room exactly you will live in, but you need to know that you precisely will have one to live in.
When you ask for dynamic memory allocation, you get some portion of memory. This memory can be allocated almost anywhere, like a room in hotel, and of course you need a key with number to know where to find it. A pointer is like that number on the key - it grants you access to your allocated data.
Also one year you may decide not to go on vacation and rent a room at all. You can't do this with your flat - you have just got it, live there or not. It's like static memory in program.
The size and location (memory address) of objects of automatic and static storage duration is known at compile time. The objects can be accessed through variables and the compiler handles the memory implicitly.
Dynamic memory on the other hand, is allocated at run time, as the name implies. Because it happens at runtime, the compiler can not have knowledge of where the memory is allocated and therefore can not handle the memory for the you. You must access the memory using it's address.
How to get the address of dynamically allocated memory?
It is returned by the new operator which allocates the memory and constructs the object. Since using dynamic memory just in one statement is not useful, you must store the address in a variable.
What type of variable can store a memory address of an object?
A pointer type. The type of the return value of a new-expression is a pointer to the type of object you constructed.
An example:
void foo() {
Foo f; // The object of type Foo has automatic storage and can be accessed through the variable `f`.
Foo* f_ptr; // The pointer object has automatic storage and is not yet initialized.
new Foo; // Bad! The dynamically allocated memory can not be accessed in any way (it has leaked).
f_ptr = new Foo; // The address of another dynamically allocated object is assigned to the f_ptr variable. The object is accessible through this pointer.
delete f_ptr; // Dynamically allocated objects must be deleted explicitly.
// f and f_ptr are destroyed automatically when the scope ends. If the memory pointed by f_ptr was not deleted before this, the memory would leak.
}
The question itself is a bit nonsensical. The keyword new is for allocating memory on the heap and returns either a pointer to the allocated object or throws a std::bad_alloc if allocation fails. It's in a sense like asking why int main(int argc, char** argv) returns an int.
In C++ you have two address spaces to work with; the stack and the heap.
Generally you want to use the heap for allocating your objects and pass them to functions either by reference, the preferred way, or by pointer. In some cases you can't use the stack, mainly when you either don't know how long the object you are creating is going to be alive or when you know that the object should live longer than the scope that creates it. For those cases you should be using std::unique_ptr or std::shared_ptr if you are using C++11 since the object will be deleted automatically when it's no longer needed.
Use of the keyword new is generally discouraged and should only be used when you're certain that neither of the above works.
To read up on the operator new:
cppreference.com
wikipedia
shared_ptr:
cppreference.com
Difference between stack and heap:
learncpp.com
The function you use (for example: malloc() in c) try to get a part of the memory with the length you asked and then it gives you the address of this part of the memory if the allocation was successful else it gives you a 0 (in c and c++ at least).
(When you want to have memory for an array of n items, you must ask for n * item size and you will get the address of the array which is also the address of the first element of your array in fact.)
Example: I want an array of 10 integers
// ask for allocation and get the address of the memory
int * my_array = (int *)malloc(10*sizeof(int));
// you must verify that the allocation was successful
if(my_array != 0) {
// the system gave you the memory you need
// you can do your operations
// " * my_array " and " my_array[0] " have the same meaning
my_array[0] = 22;
* my_array = 22;
// This two lines make the same thing : the put 22 in the memory at the adresse my_array
// same thing for " *(my_array + 9*sizeof(int)) " and " my_array[9] "
my_array[9] = 50;
*(my_array + 9*sizeof(int)) = 50;
// This two lines make the same thing : the put 50 in the memory at the adresse my_array + 36
// 36 = 9*4 (sizeof(int) = 4 in most cases)
free(my_array); //always free the memory to give back the memory to the system and do not "lost it"
}
It is the same in c++ but you replace malloc by new and free by delete. They are keyword but you can see them as functions to understand what it is done.
This question already has answers here:
What happens in a double delete?
(8 answers)
Closed 8 years ago.
I was studying about creating a object with pointer using dynamic allocation. And i read that when an object is created once and its deleted twice,The heap memory gets corrupted. what does corrupted means? Is it similar to memory leak or is it something else?
int main()
{
//consider my class name is sample
sample *p= new sample;
//some code
delete p;
//some code
delete p;
}
when i delete the p for the first time, the memory pointed by p gets cleared and returns safely to the heap. what happens the next time?
The free store is a carefully managed system of free and allocated blocks, and new and delete do bookkeeping to keep everything in a consistent state. If you delete again, the system is likely to do the same bookkeeping on invalid data, and suddenly the free store is in an inconsistent state. This is known as "heap corruption".
Once that happens, anything you do with new or delete may have unpredictable results, which can include attempting to write outside the application's memory area, corrupting data, erroneously thinking there's no more memory, or overlapping allocation.
Safest bet is always set pointer to null after deleting it.
int *ptr = new int;
// do something
delete ptr;
ptr = null;
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
What is the difference between:
int myArray[5];
and
int* myArray = new int[5];
int myArray[5] is a bunch of five integers with automatic (or static) storage duration (local memory, often classified as "in stack"). Local memory gets cleared in C++ when the specific scope is exited.
int* myArray = new int[5] is a bunch of five integers on with dynamic storage duration (dynamic memory, often classified as "in heap"). Dynamic memory won't get cleared when the specific scope is exited (myArray has to be an int pointer to store the location of your dynamically created memory).
View the following example:
void foo(){
int myArray[5];
}
void bar(){
int* myArray_dynamic = new int[5];
}
int main(){
foo();
bar();
}
foo will use stack memory, so when foo returns/exits the memory will get freed automatically. However, the dynamic allocated memory, which location is stored in myArray_dynamic in bar won't get freed, as the compiler will only free the memory of myArray_dynamic, not the memory that's stored at its value.
This will create a memory leak, so for every use of new or new[] there has to be a call of delete or delete[] (except you are working with smart pointers, but that's for another question).
The correct version of bar is
void bar(){
int* myArray_dynamic = new int[5];
delete[] myArray_dynamic;
}
The primary reason to pick one or the other is that dynamic allocation is slower, but can be any size (automatic arrays must have a fixed compile-time size), and also that space on the stack is limited, and if you run out, very bad things happen.
The first is an array that's a block of memory allocated either statically or as an automatic variable on the stack during the execution of a function ... it really depends on the context in which its declared/defined.
The second won't compile :-)
To be serious, you really want:
int* myArray = new int[5];
which means we've declared a pointer-type variable that points to an array of integers, and the array of integers is allocated dynamically by the C++ runtime on the heap by the call to new, which is a segment of memory allocated by the OS for your process to dynamically allocate variables in.
The difference is the lifetime.
int myArray[5];
This reserves storage for an array 5 of int. If myArray is declared at block scope, the array is discarded at the end of the block where it is declared.
int* myArray = new int[5];
This dynamically allocates an array 5 of int, the array exists until it is freed with delete [].
What is the difference
One is valid.
The other is not.
In the second you must write
int* myArray = new int[5];
new retuns pointer to the area dynamically allocated in heap.
I know that memory alloced using new, gets its space in heap, and so we need to delete it before program ends, to avoid memory leak.
Let's look at this program...
Case 1:
char *MyData = new char[20];
_tcscpy(MyData,"Value");
.
.
.
delete[] MyData; MyData = NULL;
Case 2:
char *MyData = new char[20];
MyData = "Value";
.
.
.
delete[] MyData; MyData = NULL;
In case 2, instead of allocating value to the heap memory, it is pointing to a string literal.
Now when we do a delete it would crash, AS EXPECTED, since it is not trying to delete a heap memory.
Is there a way to know where the pointer is pointing to heap or stack?
By this the programmer
Will not try to delete any stack memory
He can investigate why does this ponter, that was pointing to a heap memory initially, is made to refer local literals? What happened to the heap memory in the middle? Is it being made to point by another pointer and delete elsewhere and all that?
Is there a way to know where the pointer is pointing to heap or stack?
You can know this only if you remember it at the point of allocation. What you do in this case is to store your pointers in smart pointer classes and store this in the class code.
If you use boost::shared_ptr as an example you can do this:
template<typename T> void no_delete(T* ptr) { /* do nothing here */ }
class YourDataType; // defined elsewhere
boost::shared_ptr<YourDataType> heap_ptr(new YourDataType()); // delete at scope end
YourDataType stackData;
boost::shared_ptr<YourDataType> stack_ptr(&stackData, &no_delete); // never deleted
As soon as you need that knowledge you have already lost. Why? Because then even if you omit the wrong delete[], you still have a memory leak.
The one who creates the memory should always be the one who deletes it. If at some occasion a pointer might get lost (or overwritten) then you have to keep a copy of it for the proper delete.
There is no way in Standard C++ of determining whether a pointer points to dynamically allocated memory or not. And note that string literals are not allocated on the stack.
As most of the users said here there's no standard way to discover which memory you're dealing with.
Also, as many users pointed out, it;s a kinda perverted situation where you pass a pointer to a function which should delete it automatically if it's allocated on heap.
But if you insist, nevertheless there are some ways to discover which memory belongs to which type.
You actually deal with 3 types of memory
Stack
Heap
Global
For instance:
char* p = new char[10]; // p is a pointer, points to heap-allocated memory
char* p = "Hello, world!"; // p is a pointer, points to the global memory
char p[] = "Hello, world!"; // p is a buffer allocated on the stack and initialized with the string
Now let's distinguish them. I'll describe this in terms of Windows API and x86 assembler (since this is what I know :))
Let's start from stack memory.
bool IsStackPtr(PVOID pPtr)
{
// Get the stack pointer
PBYTE pEsp;
_asm {
mov pEsp, esp
};
// Query the accessible stack region
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(pEsp, &mbi, sizeof(mbi)));
// the accessible stack memory starts at mbi.BaseAddress and lasts for mbi.RegionSize
return (pPtr >= mbi.BaseAddress) && (pPtr < PBYTE(mbi.BaseAddress) + mbi.RegionSize);
}
If the pointer is allocated on the stack of another thread you should get its stack pointer by GetThreadContext instead of just taking the EIP register value.
Global memory
bool IsGlobalPtr(PVOID pPtr)
{
MEMORY_BASIC_INFORMATION mbi;
VERIFY(VirtualQuery(pPtr, &mbi, sizeof(mbi)));
// Global memory allocated (mapped) at once for the whole executable
return mbi.AllocationBase == GetModuleHandle(NULL);
}
If you're writing a DLL you should put its module handle (which is actually its base mapping pointer) instead of GetModuleHandle(NULL).
Heap
Theoretically you may assume that if the memory is neither global nor stack - it's allocated on heap.
But there's is actually a big ambiguity here.
You should know that there're different implementations of the heap (such as raw Windows heap accessed by HeapAlloc/HeapFree, or CRT-wrapped malloc/free or new/delete).
You may delete such a block via delete operator only if you know for sure it was either stack/global pointer or it was allocated via new.
In conclusion:
It's a kinda pervert trick. Should not be used generally. Better to provide some extra information with the pointer which tells how to release it.
You can only use it if you know for sure on which heap the memory was allocated (in case it's a heap memory).
I think there is no (easy) way how to tell where the memory is allocated (you might be able to determine it using a debugger, perhaps, but that is obviously not what you want). The bottom line is: never do the thing you did in case 2.
In case 2, MyData = "Value" causes a memory leak since there is no longer a reference to the memory returned from new.
There is no easy way or standard way for doing this. You can intercept the heap allocation function(s) and put each memory allocated zone in a list. Your "IsHeap" function should check if the zone passed to the function is the one from the list. This is just a hint - it is almost impossible to do this in a cross-platform manner.
But then again - why would you need that?