I've been haunted by this error for quite a while so I decided to post it here.
This segmentation fault happened when a cudaMemcpy is called:
CurrentGrid->cdata[i] = new float[size];
cudaMemcpy(CurrentGrid->cdata[i], Grid_dev->cdata[i], size*sizeof(float),\
cudaMemcpyDeviceToHost);
CurrentGrid and Grid_dev are pointer to a grid class object on host and device respectively and i=0 in this context. Class member cdata is a float type pointer array. For debugging, right before this cudaMemcpy call I printed out the value of each element of Grid_Dev->cdata[i], the address of CurrentGrid->cdata[i] and Grid_dev->cdata[i] and the value of size, which all looks good. But it still ends up with "Segmentation fault (core dumped)", which is the only error message. cuda-memcheck only gave "process didn't terminate successfully". I'm not able to use cuda-gdb at the moment. Any suggestion about where to go?
UPDATE: It seems now I have solved this problem by cudaMalloc another float pointer A on device and cudaMemcpy the value of Grid_dev->cdata[i] to A, and then cudaMemcpy A to host.
So the segment of code written above becomes:
float * A;
cudaMalloc((void**)&A, sizeof(float));
...
...
cudaMemcpy(&A, &(Grid_dev->cdata[i]), sizeof(float *), cudaMemcpyDeviceToHost);
CurrentGrid->cdata[i] = new float[size];
cudaMemcpy(CurrentGrid->cdata[i], A, size*sizeof(float), cudaMemcpyDeviceToHost);
I did this because valgrind popped up "invalid read of size 8", which I thought referring to Grid_dev->cdata[i]. I checked it again with gdb, printing out the value of Grid_dev->cdata[i] being NULL. So I guess I cannot directly dereference the device pointer even in this cudaMemcpy call. But why ? According to the comment at the bottom of this thread , we should be able to dereference device pointer in cudaMemcpy function.
Also, I don't know the the underlying mechanism of how cudaMalloc and cudaMemcpy work but I think by cudaMalloc a pointer, say A here, we actually assign this pointer to point to a certain address on the device. And by cudaMemcpy the Grid_dev->cdata[i] to A as in the modified code above, we re-assign the pointer A to point to the array. Then don't we lose the track of the previous address that A pointed to when it is cudaMalloced? Could this cause memory leak or something? If yes, how should I work around this situation properly?
Thanks!
For reference I put the code of the complete function in which this error happened below.
Many thanks!
__global__ void Print(grid *, int);
__global__ void Printcell(grid *, int);
void CopyDataToHost(param_t p, grid * CurrentGrid, grid * Grid_dev){
cudaMemcpy(CurrentGrid, Grid_dev, sizeof(grid), cudaMemcpyDeviceToHost);
#if DEBUG_DEV
cudaCheckErrors("cudaMemcpy1 error");
#endif
printf("\nBefore copy cell data\n");
Print<<<1,1>>>(Grid_dev, 0); //Print out some Grid_dev information for
cudaDeviceSynchronize(); //debug
int NumberOfBaryonFields = CurrentGrid->ReturnNumberOfBaryonFields();
int size = CurrentGrid->ReturnSize();
int vsize = CurrentGrid->ReturnVSize();
CurrentGrid->FieldType = NULL;
CurrentGrid->FieldType = new int[NumberOfBaryonFields];
printf("CurrentGrid size is %d\n", size);
for( int i = 0; i < p.NumberOfFields; i++){
CurrentGrid->cdata[i] = NULL;
CurrentGrid->vdata[i] = NULL;
CurrentGrid->cdata[i] = new float[size];
CurrentGrid->vdata[i] = new float[vsize];
Printcell<<<1,1>>>(Grid_dev, i);//Print out element value of Grid_dev->cdata[i]
cudaDeviceSynchronize();
cudaMemcpy(CurrentGrid->cdata[i], Grid_dev->cdata[i], size*sizeof(float),\
cudaMemcpyDeviceToHost); //where error occurs
#if DEBUG_DEV
cudaCheckErrors("cudaMemcpy2 error");
#endif
printf("\nAfter copy cell data\n");
Print<<<1,1>>>(Grid_dev, i);
cudaDeviceSynchronize();
cudaMemcpy(CurrentGrid->vdata[i], Grid_dev->vdata[i], vsize*sizeof(float),\
cudaMemcpyDeviceToHost);
#if DEBUG_DEV
cudaCheckErrors("cudaMemcpy3 error");
#endif
}
cudaMemcpy(CurrentGrid->FieldType, Grid_dev->FieldType,\
NumberOfBaryonFields*sizeof(int), cudaMemcpyDeviceToHost);
#if DEBUG_DEV
cudaCheckErrors("cudaMemcpy4 error");
#endif
}
EDIT: here is the information from valgrind, from which I'm trying to track down where the memory leak happened.
==19340== Warning: set address range perms: large range [0x800000000, 0xd00000000) (noaccess)
==19340== Warning: set address range perms: large range [0x200000000, 0x400000000) (noaccess)
==19340== Invalid read of size 8
==19340== at 0x402C79: CopyDataToHost(param_t, grid*, grid*) (CheckDevice.cu:48)
==19340== by 0x403646: CheckDevice(param_t, grid*, grid*) (CheckDevice.cu:186)
==19340== by 0x40A6CD: main (Transport.cu:81)
==19340== Address 0x2003000c0 is not stack'd, malloc'd or (recently) free'd
==19340==
==19340==
==19340== Process terminating with default action of signal 11 (SIGSEGV)
==19340== Bad permissions for mapped region at address 0x2003000C0
==19340== at 0x402C79: CopyDataToHost(param_t, grid*, grid*) (CheckDevice.cu:48)
==19340== by 0x403646: CheckDevice(param_t, grid*, grid*) (CheckDevice.cu:186)
==19340== by 0x40A6CD: main (Transport.cu:81)
==19340==
==19340== HEAP SUMMARY:
==19340== in use at exit: 2,611,365 bytes in 5,017 blocks
==19340== total heap usage: 5,879 allocs, 862 frees, 4,332,278 bytes allocated
==19340==
==19340== LEAK SUMMARY:
==19340== definitely lost: 0 bytes in 0 blocks
==19340== indirectly lost: 0 bytes in 0 blocks
==19340== possibly lost: 37,416 bytes in 274 blocks
==19340== still reachable: 2,573,949 bytes in 4,743 blocks
==19340== suppressed: 0 bytes in 0 blocks
==19340== Rerun with --leak-check=full to see details of leaked memory
==19340==
==19340== For counts of detected and suppressed errors, rerun with: -v
==19340== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
I believe I know what the problem is, but to confirm it, it would be useful to see the code that you are using to set up the Grid_dev classes on the device.
When a class or other data structure is to be used on the device, and that class has pointers in it which refer to other objects or buffers in memory (presumably in device memory, for a class that will be used on the device), then the process of making this top-level class usable on the device becomes more complicated.
Suppose I have a class like this:
class myclass{
int myval;
int *myptr;
}
I could instantiate the above class on the host, and then malloc an array of int and assign that pointer to myptr, and everything would be fine. To make this class usable on the device and the device only, the process could be similar. I could:
cudaMalloc a pointer to device memory that will hold myclass
(optionally) copy an instantiated object of myclass on the host to the device pointer from step 1 using cudaMemcpy
on the device, use malloc or new to allocate device storage for myptr
The above sequence is fine if I never want to access the storage allocated for myptr on the host. But if I do want that storage to be visible from the host, I need a different sequence:
cudaMalloc a pointer to device memory that will hold myclass, let's call this mydevobj
(optionally) copy an instantiated object of myclass on the host to the device pointer mydevobj from step 1 using cudaMemcpy
Create a separate int pointer on the host, let's call it myhostptr
cudaMalloc int storage on the device for myhostptr
cudaMemcpy the pointer value of myhostptr from the host to the device pointer &(mydevobj->myptr)
After that, you can cudaMemcpy the data pointed to by the embedded pointer myptr to the region allocated (via cudaMalloc) on myhostptr
Note that in step 5, because I am taking the address of this pointer location, this cudaMemcpy operation only requires the mydevobj pointer on the host, which is valid in a cudaMemcpy operation (only).
The value of the device pointer myint will then be properly set up to do the operations you are trying to do. If you then want to cudaMemcpy data to and from myint to the host, you use the pointer myhostptr in any cudaMemcpy calls, not mydevobj->myptr. If we tried to use mydevobj->myptr, it would require dereferencing mydevobj and then using it to retrieve the pointer that is stored in myptr, and then using that pointer as the copy to/from location. This is not acceptable in host code. If you try to do it, you will get a seg fault. (Note that by way of analogy, my mydevobj is like your Grid_dev and my myptr is like your cdata)
Overall it is a concept that requires some careful thought the first time you run into it, and so questions like this come up with some frequency on SO. You may want to study some of these questions to see code examples (since you haven't provided your code that sets up Grid_dev):
example 1
example 2
example 3
Related
The loop in the following code can be executed a few times but then it crashes.
#include <cstdlib>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
//not needed but program will not crash if I remove it
int blocksize=stoi(argv[1]);
//typical value 70-100
int min_length=stoi(argv[2]);
for(int i=0;i<250000;i++)
{
//Allocate memory for new integer array[row][col]. First allocate the memory for the top-level array (rows).
int **output_std = (int**) malloc(20*sizeof(int*));
//Allocate a contiguous chunk of memory for the array data values.
output_std[0] = (int*) malloc( min_length*20*sizeof(int) );
//Set the pointers in the top-level (row) array to the correct memory locations in the data value chunk.
for (int k=1; k < 20; k++)
{
output_std[k] = output_std[0]+k*min_length;
}
//do something with output_std
//free malloc'd space
free(output_std[0]);
for(int k=0;k<20;k++)
{
output_std[i]=NULL;
}
free(output_std);
output_std=NULL;
}
return 0;
}
Debugging with GDB points to line 36: free(output_std);.
Debugging with valgrind yields the following error:
nvalid write of size 8
==32161== at 0x4031A0: main (test.cpp:31)
==32161== Address 0x82f2620 is 0 bytes after a block of size 160 alloc'd
==32161== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32161== by 0x403159: main (test.cpp:16)
Line 16 is: int **output_std = (int**) malloc(20*sizeof(int*));
Line 31 is: free(output_std[0]);
Why do I get different positions for the error in my code?
How to proceed in such a situation?
(How can I fix my code?)
Edit: The lines are correct. I need such an object for a third party library.
Valgrind can often detect the problem earlier. That's the point of using it. Valgrind often catches the origin of the problem (or gets closer to the origin), while in GDB you can only see the consequences.
In your case the origin of the problem is heap memory corruption caused by an out-of-bounds write into an array. The consequence is crash inside free caused by that heap corruption. Valgrind catches the former. When you run your program (e.g. under GDB) you can only see the latter.
In your code
for(int k=0;k<20;k++)
{
output_std[i]=NULL;
}
the intended iteration variable is k. But you are accessing your array at i. At this point i is apparently 20, which results in out-of-bounds access caught by valgrind.
I'd say this cycle is rather pointless anyway: you are trying to zero out memory that you are about to deallocate immediately after that. One can provide some arguments as to why it might make sense... But things like this are more appropriate inside the memory deallocation function itself, in debug version of the library. In user-level code it just clutters the code with unnecessary noise.
P.S. In any case, you apparently posted invalid line numbers. If free(output_std) is line 36, then the offending line should be seen by valgrind as 34, not 31. Please, next time post accurate code and strive to accurately identify the offending lines.
valgrind replaces memory allocation and deallocation functions with its own instrumented versions. You can see that in the output:
at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
This is why under valgrind the application may crash in another place.
I am trying to understand how vectors work. From what I ve read they are a class that can be used as an array with many helpful functions to handle its elements. So I ve tried creating a vector of a class A which contains a vector of class B.
Here is the code:
#include <iostream>
#include <vector>
using namespace std;
class B
{
public:
B()
{}
void print()
{
cout<<"The mighty ";
}
~B()
{}
};
class A
{
B b;
vector<B> Blist;
public:
A()
{
cout<<"An A!"<<endl;
}
void pushb()
{
Blist.push_back(b);
}
void printb()
{
Blist[7].print();
}
void print()
{
cout<<"Kass Company"<<endl;
}
~A()
{
}
};
int main(void)
{
vector<A> Alist;
A a, b, c;
Alist.push_back(a);
Alist[1].printb();
Alist[1].print();
return 0;
}
Well, my problem is that... it works fine. If vectors work like arrays shouldnt the first object that gets pushbacked get the 0 position of the vector? As a result, shouldnt the program fail to run, since there is no object in the Alist[1] or the Blist[7]?
Thanks in advance!
Well, my problem is that... it works fine
Well, in fact it shouldn't, since you're accessing both Alist and Alist::Blist out of their bounds.
If vectors work like arrays shouldnt the first object that gets pushbacked get the 0 position of the vector?
The std::vector<T>::push_back function appends an element to the end of the vector, so the push-backed element is given the index size() - 1 (after the push, e.g. the old size()).
Check your bounds
When using std::vector, you are responsible for checking the bounds you're trying to access to. You can use std::vector<T>::size() for this check, or the function std::vector<T>::at(size_t) as said by Jarod42.
See the STL documentation for more information : http://www.cplusplus.com/reference/vector/.
Why it seems to work anyway
You're stumbling across undefined behavior but still, it seems to work fine. Why ?
Well, internally the vector holds a pointer to dynamically allocated memory, holding the vector contents. The class encapsulates all the nasty memory management (calling new, delete, resizing the array, etc.).
When you're calling std::vector<T>::operator[](size_t), by doing for example Alist[1], it simply boils down to dereferencing the internal array at the given index (without bound checking).
Using a bad index, you end up reading some memory past the end of the allocated region, that does not contain any meaningful data, and is probably either uninitialized or zero'ed out. In conclusion when you're doing Alist[1], you're getting some garbage memory interpreted as an A instance.
Now why the hell doing Alist[1].print() does not crash ? Because the function A::print() is not using of the class members, and doing a->print() simply does not uses a contents.
You can verify this using this program (please don't actually use this, it is just intended for this demonstration) :
int foo = 0xDEADBEEF;
A& z = static_cast<A&>(*((A*) &foo));
z.print();
This code simply uses the memory occupied by the integer value foo as an A instance (much like you're using uninitialized memory when accessing the vector out of bounds), and calls the A::print() function.
You can try this for yourself, it works as expected ! This is because this member function does not need to use the actual memory content of the instance, and will run no matter z points to garbage or not.
How to debug and check this program
Use valgrind (http://valgrind.org/). Definitely.
Using valgrind's memcheck, you can track down invalid reads and writes (as well as other memory related stuff) :
you$ valgrind --tool=memcheck a.out
==1785== Memcheck, a memory error detector
==1785== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1785== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==1785== Command: ./a.out
==1785==
An A!
An A!
An A!
==1785== Invalid read of size 8
==1785== at 0x400F14: std::vector<B, std::allocator<B> >::operator[](unsigned long) (stl_vector.h:771)
==1785== by 0x400E02: A::printb() (main.c:34)
==1785== by 0x400C0D: main (main.c:51)
==1785== Address 0x5a12068 is 8 bytes after a block of size 32 alloc'd
==1785== at 0x4C28965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1785== by 0x4022E5: __gnu_cxx::new_allocator<A>::allocate(unsigned long, void const*) (new_allocator.h:104)
==1785== by 0x401D20: std::_Vector_base<A, std::allocator<A> >::_M_allocate(unsigned long) (in /home/amonti/.local/share/people/temp/a.out)
==1785== by 0x4013F8: std::vector<A, std::allocator<A> >::_M_insert_aux(__gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >, A const&) (vector.tcc:345)
==1785== by 0x401017: std::vector<A, std::allocator<A> >::push_back(A const&) (stl_vector.h:913)
==1785== by 0x400BF4: main (main.c:50)
==1785==
The mighty Kass Company
==1785==
==1785== HEAP SUMMARY:
==1785== in use at exit: 0 bytes in 0 blocks
==1785== total heap usage: 1 allocs, 1 frees, 32 bytes allocated
==1785==
==1785== All heap blocks were freed -- no leaks are possible
==1785==
==1785== For counts of detected and suppressed errors, rerun with: -v
==1785== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3)
In this trace valgrind detects an invalid read (of size 8 because you're reading a pointer on a 64-bit platform) at main.c:34 :
Blist[7].print();
So you can verify that you're doing something wrong.
in your case the output maybe a trash result because the logic of the vector data structure is that its a dynamic array that expands it self(by a constant range ) when it reaches the last free space .
for example when first creating a vector it has 10 spaces when it reaches the 10 space it becomes 20 and in this stage the vec[11] has a trash value.
This is exactly why you're supposed to use vector::at() instead of vector::operator[] when you're testing/writing your program for the first time.
You can use macros and preprocessor defines to declare that you're compiling for debug, such as:
#ifdef THISISDEBUG
return myvec.at(5);
#else
return myvec[5];
#endif
Then you tell your makefile to define THISISDEBUG when you're debugging/testing.
The difference between at() and operator[], is that at() throws an exception if you're out of range, while operator[] accesses memory directly.
In C++, you're generally allowed to read any place in memory (at least in Windows and Linux), but you're only allowed to write into places that belong to your program. Your operating system protects you! Imagine you do what you did up there, and you try to modify something that doesn't belong to your proram. Back then in the 80s and 90s, this would've been accepted and would've lead to a blue screen. Now, your operating system raises a SEGFAULT.
On the other hand, the reason why you're seeing a result there, is because deleting an object doesn't necessarily mean resetting values in memory. It just means that your program tells the operating system: "look, I don't need this region of memory anymore". So, your operating system can assign this region to another program. So, if you try to read that region again, it will work, but you'll get garbage! That's exactly what this technically is called. Like when you do:
double x;
std::cout << x << std::endl;
What is the value that will be printed? It's garbage. It's the remnant of some other program that freed that memory.
Basicly vectors are arrays class.
vector <string> arr; // defines that this is array
vector <MyClass *> arrw; // defines that this is array to my created class vector
Vector is useful to use, when you don't know how much array elements you need. For example, read lines from file. To add new element to vector you can use arr.insert(arr.end(), ""); and add.insert(arr.end(), new MyClass); (I like this better then push_back, becouse You can insert in any place of vector.)
You can access you array element by the same way:
arr[2];
Also it's useful to know some tricks like get access to last element; arr[arr.size() - 1] i. (arr.size() will return INT [elements in array]. And -1 will count it for good index. Othewise you will get segmentation error).
P.S. There is no difference between vector Class and array, ecxept this methods, that allow add new elements, when you don't know how big your array will be.
I want to allocate memory for a struct that contains std::vector. After allocating it, I will push_back some data to it.
After all, I need to destroy my allocated struct. I want to know how can it be done with no memory corruption.
Here is my code:
typedef struct my_struct_t{
int a, b;
vector<unsigned> vec;
}
} MYSTRUCT;
int main(int argc, const char * argv[])
{
MYSTRUCT* ptr_s = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s->vec.push_back(i);
}
ptr_s->vec.clear();
delete ptr_s;
return 0;
}
I tried to use clear as it is supposed to call destructor. But after valgrind-ing my code, there are still some blocks reachable. I also tried to deallocate vector using this:
vector<unsigned>().swap(ptr_s.vec)
But with no success.
output of `valgrind':
==52635== HEAP SUMMARY:
==52635== in use at exit: 10,360 bytes in 5 blocks
==52635== total heap usage: 147 allocs, 142 frees, 25,198 bytes allocated
==52635==
==52635== LEAK SUMMARY:
==52635== definitely lost: 0 bytes in 0 blocks
==52635== indirectly lost: 0 bytes in 0 blocks
==52635== possibly lost: 0 bytes in 0 blocks
==52635== still reachable: 10,360 bytes in 5 blocks
==52635== suppressed: 0 bytes in 0 blocks
==52635== Reachable blocks (those to which a pointer was found) are not shown.
==52635== To see them, rerun with: --leak-check=full --show-leak-kinds=all
Thank you everyone in advance.
update:
I noticed that the source of memory corruption in my application is in somewhere else. So I added an update. Here is the new code:
MYSTRUCT* ptr_s1 = new MYSTRUCT;
MYSTRUCT* ptr_s2 = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s1->vec.push_back(i);
}
memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));
delete ptr_s1;
delete ptr_s2; // here I get seg fault
return 0;
As soon as deleting ptr_s2, seg fault happens.
Update: proper way, based on the accepted answer:
typedef struct my_struct_t{
int a, b;
vector<unsigned> vec;
inline my_struct_t operator=(const my_struct_t &s ){
a = s.a;
b = s.b;
vec = s.vec;
return s;
}
} MYSTRUCT;
MYSTRUCT* ptr_s1 = new MYSTRUCT;
MYSTRUCT* ptr_s2 = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s1->vec.push_back(i);
}
// no memcpy
// memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));
*ptr_s2 = *ptr_s1;
delete ptr_s1;
delete ptr_s2; // no more sget seg fault
return 0;
You don't need to call std::vector::clear or do something else, the destructor will get called when you delete it via delete ptr_s;.
The still reachable matter is explained in Valgrind FAQ.
My program uses the C++ STL and string classes. Valgrind reports
'still reachable' memory leaks involving these classes at the exit of
the program, but there should be none.
First of all: relax, it's probably not a bug, but a feature. Many
implementations of the C++ standard libraries use their own memory
pool allocators. Memory for quite a number of destructed objects is
not immediately freed and given back to the OS, but kept in the
pool(s) for later re-use. The fact that the pools are not freed at the
exit of the program cause Valgrind to report this memory as still
reachable. The behaviour not to free pools at the exit could be called
a bug of the library though.
Update:
Briefly, don't copy classes with memcpy, if you use memcpy to copy a class object whose destructor deletes a pointer within itself (std::vector member in your case), you will end up with double delete when the second instance of the object is destroyed.
The right way is copy/move constructor and/or assignment operator for classes.
I'm following a book on C++ programming, and I'm following the exercises. One exercise asks me to create a program that produces a memory leak. Will this program produce such a leak?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
Considering it is a trivial example, not having a delete paired with your new is a leak. In order to prevent a leak in this case you would need the following:
int * pInt = new int;
*pInt = 20;
delete pInt ;
pInt = new int;
*pInt =50;
delete pInt ;
A decent tool to use to detect memory leaks is Valgrind. I ran the tool on your sample code, like so:
valgrind ./a.out
and this is part of the output it produced:
==14153== HEAP SUMMARY:
==14153== in use at exit: 8 bytes in 2 blocks
==14153== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==14153==
==14153== LEAK SUMMARY:
==14153== definitely lost: 8 bytes in 2 blocks
Which confirms that indeed the program does leak memory.
Yes. To avoid leaks, every time you call new, you have to have a matching call to delete. You have 2 calls to new and no calls to delete, so you have 2 leaks.
Note that when your program exits, the OS will free up all the memory you've allocated with new. So memory leaks are really only a problem for non-trivial programs.
One exercise asks me to create a program that produces a memory leak.
Will this program produce such a leak?
an utter exercise , and your code is a better answer to exercise !
Pointers and memory leaks. These are truly the items that consume most of the debugging time for developers
Memory leak
Memory leaks can be really annoying. The following list describes some scenarios that result in memory leaks.
Reassignment, I'll use an example to explain reassignment.
char *memoryArea = malloc(10);
char *newArea = malloc(10);
This assigns values to the memory locations shown in Figure 4 below.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig4.gif
Figure 4. Memory locations
memoryArea and newArea have been allocated 10 bytes each and their respective contents are shown in Figure 4. If somebody executes the statement shown below (pointer reassignment )
memoryArea = newArea;
then it will surely take you into tough times in the later stages of this module development.
In the code statement above, the developer has assigned the memoryArea pointer to the newArea pointer. As a result, the memory location to which memoryArea was pointing to earlier becomes an orphan, as shown in Figure 5 below. It cannot be freed, as there is no reference to this location. This will result in a memory leak of 10 bytes.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig5.gif
Figure 5. Memory leak
Before assigning the pointers, make sure memory locations are not becoming orphaned.
Freeing the parent block first
Suppose there is a pointer memoryArea pointing to a memory location of 10 bytes. The third byte of this memory location further points to some other dynamically allocated memory location of 10 bytes, as shown in Figure 6.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig6.gif
Figure 6. Dynamically allocated memory
free(memoryArea)
**If memoryArea is freed by making a call to free, then as a result the newArea pointer also will become invalid. The memory location to which newArea was pointing cannot be freed, as there is no pointer left pointing to that location. In other words, the memory location pointed by newArea becomes an orphan and results in memory leak.
Whenever freeing the structured element, which in turn contains the pointer to dynamically allocated memory location, first traverse to the child memory location (newArea in the example) and start freeing from there, traversing back to the parent node.
The correct implementation here will be:
free( memoryArea->newArea);
free(memoryArea);
Improper handling of return values
At time, some functions return the reference to dynamically allocated memory. It becomes the responsibility of the calling function to keep track of this memory location and handle it properly.**
char *func ( )
{
return malloc(20); // make sure to memset this location to ‘\0’…
}
void callingFunc ( )
{
func ( ); // Problem lies here
}
In the example above, the call to the func() function inside the callingFunc() function is not handling the return address of the memory location. As a result, the 20 byte block allocated by the func() function is lost and results in a memory leak.
Sharp Reference at :
http://www.ibm.com/developerworks/aix/library/au-toughgame/
Update:
your interest let me for an edit
Simple rules to avoid Memory Leaks in C
You are allocating memory for p and q:
p=new int [5];
/* ... */
q=new int;
But you are only freeing p using an invalid operator, since arrays should be deleted using delete[]. You should at some point free both p and q using:
delete[] p;
delete q;
Note that since you are making your pointers point to the other pointer's allocated buffer, you might have to check which delete operator corresponds to which new operation.
You should use delete[] on the buffer allocated with new[] and delete with the buffer allocated with new.
Rule 1: Always write “free” just after “malloc”
int *p = (int*) malloc ( sizeof(int) * n );
free (p);
Rule 2: Never, ever, work with the allocated pointer. Use a copy!
int *p_allocated = (int*) malloc ( sizeof(int) * n );
int *p_copy = p_allocated;
// do your stuff with p_copy, not with p_allocated!
// e.g.:
while (n--) { *p_copy++ = n; }
...
free (p_allocated);
Rule 3: Don’t be parsimonious. Use more memory.
Always start by allocating more memory than you need. After you finish debugging, go back and cut on memory use. If you need an array 1000 integers long, allocate 2000, and only after you make sure everything else is OK – only then go back and cut it down to 1000.
Rule 4: Always carry array length along with you
Wherever your array goes, there should go with it it’s length. A nice trick is to allocate an array sized n+1, and save n into it’s 0 place:
int *p_allocated = (int*) malloc ( sizeof(int) * (n+1) );
int *p_copy = p_allocated+1;
p_copy[-1] = n;
// do your stuff with p_copy, not with p_allocated!
free (p_allocated);
Rule 5: Be consistent. And save comments
The most important thing is to be consistent and to write down what you do. I am always amazed at how many programmers seem to think that comments are a waste of time. They are imperative. Without comments, you probably won’t remember what you did. Imagine returning to your code a year after you wrote it, and spending countless hour trying to recall what that index does. Better to spend a couple of seconds writing it down.
Also, if you are consistent, you will not fail often. Always use the same mechanism for passing arrays and pointers. Don’t change the way you do things lightly. If you decide to use my previous trick, use it everywhere, or you might find yourself referring back to a nonexistent place because you forgot what type of reference you chose.
Ref : http://mousomer.wordpress.com/2010/11/03/simple-rules-to-avoid-memory-leaks-in-c/
Yes, this produces not one, but two memory leaks: both allocated ints are leaked. Moreover, the first one is leaked irrecoverably: once you assign pInt a new int the second time, the first allocated item is gone forever.
Will this program produce suck a leak?
Yes, it will.
Yes and no. When pInt is overwritten with a new int pointer, you lose that memory that was previously allocated, however when the program returns, most modern operating systems will clean up this memory, as well as the memory lost by not deallocating pInt at the end.
So in essence, yes, something like this will result in two memory leaks.
It does, because you allocate space with the statement "new int", but do not use "delete" to free the space.
Consider the following C++ program:
#include <cstdlib> // for exit(3)
#include <string>
#include <iostream>
using namespace std;
void die()
{
exit(0);
}
int main()
{
string s("Hello, World!");
cout << s << endl;
die();
}
Running this through valgrind shows this (some output trimmed for brevity):
==1643== HEAP SUMMARY:
==1643== in use at exit: 26 bytes in 1 blocks
==1643== total heap usage: 1 allocs, 0 frees, 26 bytes allocated
==1643==
==1643== LEAK SUMMARY:
==1643== definitely lost: 0 bytes in 0 blocks
==1643== indirectly lost: 0 bytes in 0 blocks
==1643== possibly lost: 26 bytes in 1 blocks
==1643== still reachable: 0 bytes in 0 blocks
==1643== suppressed: 0 bytes in 0 blocks
As you can see, there's a possibility that 26 bytes allocated on the heap were lost. I know that the std::string class has a 12-byte struct (at least on my 32-bit x86 arch and GNU compiler 4.2.4), and "Hello, World!" with a null terminator has 14 bytes. If I understand it correctly, the 12-byte structure contains a pointer to the character string, the allocated size, and the reference count (someone correct me if I'm wrong here).
Now my questions: How are C++ strings stored with regard to the stack/heap? Does a stack object exist for a std::string (or other STL containers) when declared?
P.S. I've read somewhere that valgrind may report a false positive of a memory leak in some C++ programs that use STL containers (and "almost-containers" such as std::string). I'm not too worried about this leak, but it does pique my curiosity regarding STL containers and memory management.
Calling exit "terminates the program without leaving the current block and hence without
destroying any objects with automatic storage duration".
In other words, leak or not, you shouldn't really care. When you call exit, you're saying "close this program, I no longer care about anything in it." So stop caring. :)
Obviously it's going to leak resources because you never let the destructor of the string run, absolutely regardless of how it manages those resources.
Others are correct, you are leaking because you are calling exit. To be clear, the leak isn't the string allocated on the stack, it is memory allocated on the heap by the string. For example:
struct Foo { };
int main()
{
Foo f;
die();
}
will not cause valgrind to report a leak.
The leak is probable (instead of definite) because you have an interior pointer to memory allocated on the heap. basic_string is responsible for this. From the header on my machine:
* A string looks like this:
*
* #code
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
* _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* #endcode
*
* Where the _M_p points to the first character in the string, and
* you cast it to a pointer-to-_Rep and subtract 1 to get a
* pointer to the header.
They key is that _M_p doesn't point to the start of the memory allocated on the heap, it points to the first character in the string. Here is a simple example:
struct Foo
{
Foo()
{
// Allocate 4 ints.
m_data = new int[4];
// Move the pointer.
++m_data;
// Null the pointer
//m_data = 0;
}
~Foo()
{
// Put the pointer back, then delete it.
--m_data;
delete [] m_data;
}
int* m_data;
};
int main()
{
Foo f;
die();
}
This will report a probable leak in valgrind. If you comment out the lines where I move m_data valgrind will report 'still reachable'. If you uncomment the line where I set m_data to 0 you'll get a definite leak.
The valgrind documentation has more information on probable leaks and interior pointers.
Of course this "leaks", by exiting before s's stack frame is left you don't give s's destructor a chance to execute.
As for your question wrt std::string storage: Different implementations do different things. Some allocate some 12 bytes on the stack which is used if the string is 12 bytes or shorter. Longer strings go to the heap. Other implementations always go to the heap. Some are reference counted and with copy-on-write semantics, some not. Please turn to Scott Meyers' Effective STL, Item 15.
gcc STL has private memory pool for containers and strings. You can turn this off ; look in valgrind FAQ
http://valgrind.org/docs/manual/faq.html#faq.reports
I would avoid using exit() I see no real reason to use that call. Not sure if it will cause the process to stop instantly without cleaning up the memory first although valgrind does still appear to run.