I have a c++ program and I want to tracking the heap memory when running
int MyFunction(){
//do function logic here
//do function logic here
.....................
//Check memory state in heap at the end of function
_CrtMemState crtMemState;
_CrtMemCheckpoint(&crtMemState);
printf("Memory: %d\n",crtMemState.lTotalCount);
}
int main(){
while(true){//Yes infinitive for long run test
MyFunction();
}
}
I got the result of memory :
Memory: 47435440
Memory: 76571670
Memory: 105710436
Memory: 135412510
Memory: 164726468
Memory: 194256398
Memory: 223569972
......
It's mean that the memory is increase for each function execution.
Does this mean MyFunction() has leak?
I tried some method like visual leak detector or _CRT* relate function but have no report about leak. My program running with memory increase by time ( I used PerfMonitor to check)
It doesn't mean it leaks
If we look at this code :
#include <iostream>
#include <vector>
int MyFunction(){
// no leak
static std::vector<int> v;
v.push_back(1);
std::cout << "memory used : " << v.size() * sizeof(int) << std::endl;
}
int main(){
while(true){//Yes infinitive for long run test
MyFunction();
}
}
this will produce :
memory used : 40140
memory used : 40144
memory used : 40148
File size limit exceeded
The vector will, at some time, ask for more memory than the PC can give, and the program will crash.
So if your MyFunction will be called an huge number of time, your program will crash too.
But it's not always a leak. May be, May be not.
In my code there is no leak, and the vector will be destroy after the main (well no because of the while(1) but we know how to clean the memory).
A leak is a memory we can't destroy anymore because we "lost" where it is. Like this :
int MyFunction(){
// leak
new int();
}
Here we can't call delete on this int because its address is long lost.
You may read the paragraph about Syntactic vs Semantic Memory Leaks here.
Related
I am taking a class on c++ for which I need to write a simple program that leaks memory on purpose. I have tried this by creating new char [] and not deleting them, but this does not seem to work. Below is the complete code I have tried.
#include <iostream>
#include <cstring>
int main()
{
int i=1;
while (i<1000){
char *data = new char [100000000];
*data = 15;
i++;
}
}
When I watch the memory usage of the program it does not grow so it is not leaking any memory. I just get a bad allocation error.
I think the simplest case of memory leakage is dynamically creating an object then immediately losing the reference to it. In this short example, you are immediately losing a reference to the variable you've created, causing the memory leak. Memory leaks in small, contrived programs like these make it hard to appreciate memory leaks because as soon as a program exits, the operating system reclaims the memory the program allocated.
The problem becomes serious when the program runs for long periods of time. The memory leak is exacerbated and computer performance is noticeable hampered.
Example:
#include <iostream>
// Object is being created, allocated on the heap then function immediately exits, losing any reference to the object. This is a memory leak
void createObject()
{
int* x = new int;
}
int prompt()
{
int response;
std::cout << "Run again?\n";
std::cin >> response;
return response;
}
int main()
{
while(continue)
{
createObject();
// Running the program again and again will exacerbate the memory leak.
continue = prompt();
}
return 0;
}
Correct way to retain object reference in this contrived and useless example:
int* createObject()
{
int* x = new int;
return x;
}
int main()
{
// Pointer to the object created in the function in this scope is created, so we still have access to the variable.
int* a = createObject();
return 0;
}
Hope this helps, good luck in your class!
If you put some delay in the loop, you will be able to see the memory grow.
You can use sleep or wait for input from the user.
As it is now, the memory inflate so fast till you run out of allocation memory.
This is not a classic test of memory leak.
Memory leak it tested at the end of the program to see if you released all the memory.
I have some question about the delete[] p. I've written some code snippet for test this function. But I found that after executing the delete[] p, only the first 2 array elements were deallocated while the remaining not. Please see my test snippet and the output result as below. Who can tell me why and how can I clear off the whole memory for the unused array? Thanks!
#include <iostream>
using namespace std;
int main()
{
int *p;
p = new int[20];
for(int i=0;i<20;i++)
{
p[i]=i+1;
}
cout<<"------------------------Before delete-------------------------"<<endl;
for(int i=0;i<20;i++)
{
cout<<"p+"<<i<<":"<<p+i<<endl;
cout<<"p["<<i<<"]:"<<p[i]<<endl;
}
delete[] p;
cout<<"-------------------After delete------------------------"<<endl;
for(int i=0;i<20;i++)
{
cout<<"p+"<<i<<":"<<p+i<<endl;
cout<<"p["<<i<<"]:"<<p[i]<<endl;
}
return 0;
}
OUTPUT IN www.compileronline.com
Compiling the source code....
$g++ main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
------------------------Before delete-------------------------
p+0:0xa90010
p[0]:1
p+1:0xa90014
p[1]:2
p+2:0xa90018
p[2]:3
p+3:0xa9001c
p[3]:4
p+4:0xa90020
p[4]:5
p+5:0xa90024
p[5]:6
p+6:0xa90028
p[6]:7
p+7:0xa9002c
p[7]:8
p+8:0xa90030
p[8]:9
p+9:0xa90034
p[9]:10
p+10:0xa90038
p[10]:11
p+11:0xa9003c
p[11]:12
p+12:0xa90040
p[12]:13
p+13:0xa90044
p[13]:14
p+14:0xa90048
p[14]:15
p+15:0xa9004c
p[15]:16
p+16:0xa90050
p[16]:17
p+17:0xa90054
p[17]:18
p+18:0xa90058
p[18]:19
p+19:0xa9005c
p[19]:20
-------------------After delete------------------------
p+0:0xa90010
p[0]:0
p+1:0xa90014
p[1]:0
p+2:0xa90018
p[2]:3
p+3:0xa9001c
p[3]:4
p+4:0xa90020
p[4]:5
p+5:0xa90024
p[5]:6
p+6:0xa90028
p[6]:7
p+7:0xa9002c
p[7]:8
p+8:0xa90030
p[8]:9
p+9:0xa90034
p[9]:10
p+10:0xa90038
p[10]:11
p+11:0xa9003c
p[11]:12
p+12:0xa90040
p[12]:13
p+13:0xa90044
p[13]:14
p+14:0xa90048
p[14]:15
p+15:0xa9004c
p[15]:16
p+16:0xa90050
p[16]:17
p+17:0xa90054
p[17]:18
p+18:0xa90058
p[18]:19
p+19:0xa9005c
p[19]:20
The memory is cleared - there's just no requirement that the compiler will actually zero out an int in its destructor. What you're seeing is that the compiler didn't think that was necessary, so it's still there. The destructor is called though and the memory is freed.
You can see that more clearly if you did something like:
struct A {
int i;
A() : i(7) { }
~A() {
std::cout << "deleting A." << std::endl;
i = 0;
}
};
And repeat your experiment with A* p = new A[20];.
It is important to distinguis between cleared memory and deleted memory.
When memory is cleared it is initialized to some value - perhaps all zeros. But when memory is deleted or freed, it is returned to the heap. When the memory is released the memory manager is under no obligation to clear the memory. The two bytes you see being changed are likely from a debug marker used by the memory manager to help track buffer overruns.
If you want to clear all of the memory, you need to do it before you delete it - only at that point do you still have ownership of that memory. Clearing it after deleting it is operating on memory you do not own.
Say I have a class called "Object " (very original, I know). To initialize on the heap, I do:
Object object* = new Object ("arg");
To allocate on the stack:
Object object= Object("arg");
My program crashes when I use the former, and points me to this line of code in "new.cpp".
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
_THROW_NCEE(_XSTD bad_alloc, ); <---- this line
}
return (p);
}
Knowing that, how would I go about finding the error and fixing it? I assume this is corruption of heap memory of some kind?
In my experience, this typically happens when you corrupt your heap by doing something bad with a pointer like writing over the end of an object / buffer / array, or deleting an invalid pointer, or double deleting a pointer, or any other activity that corrupts the underlying data structure(s) used by the heap manager. You are observing a crash at a later stage which is just a symptom of something that happened previously.
Depending on your platform, you can check in Visual Studio by linking against the CRT debug heap, or on Linux using Electric Fence, Valgrind, etc.
Visual Studio heap debugging - http://msdn.microsoft.com/en-us/library/z8h19c37(v=vs.100).aspx
Valgrind - http://valgrind.org/info/tools.html
Electric Fence and Valgrind are typically optional packages on Linux.
Look at the following C++ code:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
class Buf
{
public:
Buf(size_t size)
{
_storage.reserve(size);
}
~Buf()
{
vector<int> temp;
_storage.swap( temp );//release memory
}
vector<int> _storage;
};
int main()
{
int i = 0;
while( ++i < 10000)
{
Buf *buf = new Buf(100000);
delete buf;
}
return 0;
}
I run it in debug mode(VS2008):when I set a break point in the line
//main function
int i = 0;
I find that the Process MyProgram.exe occupies about 300KB memory in Windows Task Manager.When I set a break point in the line
return 0;
The Process MyProgram.exe occupies about 700KB in Windows Task Manager.
My question is :why the memory that the program occupies increased?I think I have release the memory exactly~Why?
Standard memory allocator will not (usually) release memory to OS when you deallocate it. Instead it will keep it for subsequent allocations for your process.
Thus you don't see memory ussage decrease in TM even though you deallocated it.
The OS/Debug environment might employ optimization techniques and your memory releasing probably just returns it to pool; the actual memory release probably occurs on program termination
I was just wondering how you could create a system memory leak using C++. I have done some googling on this but not much came up, I am aware that it is not really feasible to do it in C# as it is managed code but wondered if there was a simple way to do this with C++? I just thought it would be interesting to see how much the system suffers because of code not being written properly. Thanks.
A memory leak occurs when you call new without calling a corresponding delete later. As illustrated in this sample code:
int main() {
// OK
int * p = new int;
delete p;
// Memory leak
int * q = new int;
// no delete
}
Create pointer to object and allocate it on the heap
Don't delete it.
Repeat previous steps
????
PROFIT
int main() {
while(true) new int;
}
There are many kinds of memory leaks:
Allocated memory that is unreleasable because nothing points to it.
These kind of leaks are easy to create in C and C++. They are also pretty easy to prevent, easy to detect, and easy to cure. Because they are easy to detect there are lots of tools, free and commercial, to help find such leaks.
Still-accessible allocated memory that should have been released a long time ago.
These kinds of leaks are much harder to detect, prevent, or cure. Something still points to it, and it will be released eventually -- for example, right before exit(). Technically speaking, this isn't quite a leak, but for all practical purposes it is a leak. Lots of supposedly leak-free applications have such leaks. All you have to do is run a system profile to see some silly application consume ever more memory. These kinds of leaks are easy to create even in managed languages.
Allocated memory that should never have been allocated in the first place.
Example: A user can easily ask Matlab to creating these kinds of leaks. Matlab is also rather aggressive at creating these kinds of leaks. When Matlab gets a failure from malloc it goes into a loop where it waits for a bit and then retries the malloc. Meanwhile, the OS frantically tries to deal with the loss of memory by shuffling chunks of programs from real memory into virtual memory. Eventually everything is in virtual memory -- and everything creeps to a standstill.
Just write an application which allocates "a lot of data" and then blocks until it is killed. Just run this program and leave it running.
class ClassWithLeakedMemory{
private:
char* str;
public:
ClassWithLeakedMemory(){
str = new char[100];
}
~ClassWithLeakedMemory(){
cout<<"We are not freeing the dynamically allocated string memory"<<endl;
}
};
class ClassWithNoLeakedMemory{
private:
char* str;
public:
ClassWithNoLeakedMemory(){
str = new char[100];
}
~ClassWithNoLeakedMemory(){
cout<<"We are freeing the dynamically allocated string memory"<<endl;
delete[] str;
str = null;
}
};
int main() {
//we are creating an automatic object of the ClassWithleakedMemory
//when we will come out of the main, this object will be
//out of scope. hence it will be deleted. so destructor will
//be called. but in the destructor, we have not specifically
//deleted the dynamically allocated string.
//so the stack based pointer object str will be deleted but the memory
//it was pointing to won't be deleted. so we will be left with an
//unreferenced memory. that is memory leak.
ClassWithLeakedMemory objectWithLeakedmemory;
ClassWithNoLeakedMemory objectWithNoLeakedmemory;
return 0;
}
The way the stack based pointer object refers to the dynamically allocated memory in both the classes can be shown pictorially as below:
In C#, just use P/Invoke to allocate a lot of memory, resource handles and keep them around.
You can use unmanaged code just fine in a simple C# harness
When an object that is created using new is no longer referenced, the delete operator has to be applied to it. If not, the memory it occupies will be lost until the program terminates. This is known as a memory leak. Here is an illustration:
#include <vector>
using namespace std;
void memory_leak(int nbr)
{
vector<int> *ptrVector = new vector<int>(nbr);
// some other stuff ...
return;
}
If we return without calling delete on the object (i.e. delete ptrToVector) a memory leak occurs. To avoid this, don't allocate the local object on the memory heap but instead use a stack-allocated variable because these get automatically cleaned up when the functions exits. To allocate the vector on the run-time stack avoid using new (which creates it on the heap) and the pointer.
It's as simple as:⠀⠀⠀
new int;
#include <stdio.h>
void main(){
for(int i = 0; i < 1000; i++)
double* ptr = (double*)malloc(1000000*sizeof(double))
//free(ptr);
ptr = NULL;
}
note : the hashed line of code caused a memory leak while the process allocated it and did't return it back to the OS