my program throws a std::bad_alloc. After debugging it, I found out it is thrown in code
curFinalBucket->points.push_back(p);
where points is a vector<PPointT> . Before the code line, curFinalBucket is initialized as follows.
PFinalBucket curFinalBucket;
curFinalBucket = (FinalBucket*)malloc(sizeof(FinalBucket));
Strange thing is that if I simply put the above code in main, no exception. But when I put it as follows,
void mergeBucket(map<BucketT, vector<PPointT>, Comp> *pMap, IntT numFinalBuckets)
{
...
PFinalBucket curFinalBucket;
curFinalBucket = (FinalBucket*)malloc(sizeof(FinalBucket));
curFinalBucket->points.push_back(p);
}
int testLoadBalancedLSH(IntT num_fbuckets, RealT avgNumPossessedTerms, IntT np, IntT d, char* dataFile)
{
...
mergeBucket(&mapstore, num_fbuckets);
}
int main(int nargs, char **args) {
...
testLoadBalancedLSH(atoi(args[1]), 0.01 * atoi(args[2]), atoi(args[2]), atoi(args[3]), args[4]);
}
it will throw the exception in question. Any ideas what this could be all about? thanks in advance.
I think the problem is you are creating curFinalBucket with malloc. This does not call the constructor so the internal vector<PPointT> is not initialized when you try to use it.
I guess FinalBucket is something like:
class FinalBucket{
public:
vector<PPointT> points;
}
points needs an initialization that is not happening because FinalBucket constructor is not being called and vector<PPointT> constructor is not being called either.
You are just allocating memory, but you need the constructors to be called for initialization to take place.
The only way around this is to use new to allocate FinalBucket.
PFinalBucket curFinalBucket;
curFinalBucket = new FinalBucket();
curFinalBucket->points.push_back(p);
(FinalBucket*)malloc(sizeof(FinalBucket)); allocates memory for an object of the size of a FinalBucket, but it doesn't actually create a final bucket. You should use new FinalBucket() for this.
Also, as a note on style, hiding pointers behind macros/typedefs like PFinalBucket makes your code harder to read. Just write FinalBucket * instead, it's much clearer.
You should use new FinalBucket to allocate dynamic memory instead of malloc. The new operator will call the constructor of FinalBucket, in which vector which be initialized.
Related
First off, this is not a duplicate. My question is how to do it with dynamic memory. The reason this is distinct is because my delete[] is hanging.
So, here's what I have:
class PacketStrRet {
public:
PacketStrRet(char p_data[], int p_len) : len(p_len) {
data = new char[p_len];
memcpy(data, p_data, p_len * sizeof(char));
}
~PacketStrRet() {
delete[] data;
data = nullptr;
}
char* data;
int len;
};
And yes, I'm aware that my code is not using the best practices. I'll clean it up later.
The problem I'm having is in the DTOR. That delete is hanging forever. The data being passed in to the CTOR is not dynamic memory, so I need to make it dynamic so things don't go out of scope. p_len holds the correct amount of data, so there's no problem there.
From what I've read, memcpy seems to be the most likely culprit here. So how do I copy a string that is not null-terminated to dynamic memory, and then still be able to delete it later?
Thanks.
The problem is not the delete, only everything that comes before and even that would be ok if there didn't occur any problems.
class PacketStrRet {
// Use RAII
std::unique_ptr<char> data; // I own this data and will destroy it.
// now the parent class is also only movable, use shared_ptr if you can't live with that.
int len;
public:
PacketStrRet(
// <RED ALERT>
char p_data[], int p_len // user can lie to us.
// </RED ALERT>
) try : // function try block, se 1)
len(p_len), data(new char[p_len]) {
memcpy(data, p_data.get(), p_len * sizeof(char));
} catch(const std::exception& e) {
std::cerr << "arg=" << arg << " failed: " << e.what() << '\n';
}
~PacketStrRet() {
// unique_ptr takes care of memory management and garbage collection.
}
// access functions
};
Now the possible errors you could make to blow the code up.
You could have copied the object, essentially making two owning raw pointers to the same data. This would blow up at delete, you coudl use memory-sanitizer / valgrind to confirm this happens. Use smart pointers to save you the trouble, the unique pointer should cause a compiler error if you tried to copy, unless you memcpy the entire structure ignoring the copy/assignment constructors.
You could give the wrong len to the constructor, what is the source of the data and len? Valgrind / memory-sanitizer can save you.
The memory corruption could happen in a totally different place. Valgrind / memory-sanitizer can save you.
In case valgrind mem-san are too much, you can try to make a check for double delete, if you make a counter in c'tor and d'tor and if it ever goes to negative you have your error.
In this class your at least missing a copy constructor. Check up on rule of 3, 5, 7 and 0 (zero) to find out how many you need.
1) http://en.cppreference.com/w/cpp/language/function-try-block
Try to use std:: copy(). It will be like this:
std::copy(p_data, p_data + p_len, data).
If I have:
template<>
char *toBytes<uint64_t>(uint64_t src) {
char *data = new char[8];
//...stuff
return data;
}
template<>
void write<uint64_t>(char *dst, uint64_t src) {
char *srcBytes = toBytes(src);
for (int i = 0; i < 8; ++i) {
*(dst++) = *(srcBytes++); //am I leaking here?
}
}
that gets called with something like:
char *keyPtr = new char[27];
//...stuff
write(keyPtr, 1234ull);
//...write up to 27
If do delete[] keyPtr; would I have deleted srcBytes? I think the question is, on the line asking if I'm leaking, is that doing a copy and as a result deleting keyPtr leaves srcBytes still to be deleted?
Still learning C++ and it's not always clear to me when the copy constructor is called vs the assignment operator.
EDIT 1:
Fixed delete as per #Steephen's answer
EDIT 2
Add toBytes as per #WhozCraig's comment
You have to use
delete [] keyPtr;
instead of calling delete over for loop;
If you allocate memory using new[], you should use delete [], and if you use new, you should use delete. In your case you are using the former one.
I think the question is, on the line asking if I'm leaking, is that
doing a copy and as a result deleting keyPtr leaves srcBytes
If your program allocated memory for srcBytes using new operator you should delete it it as same way you do for keyPtr . Because resource handling by both pointers are independent even after your assignment in your case.
You have a memory leak. No, delete []-ing keyPtrhas nothing to do with srcBytes, an independent allocation. The two addressed buffers are unrelated (except for content due to your copy-code).
Apart from the obvious (using std::vector<> and letting RAII take over the memory management for all of this), a fairly minimal change to your code to plug the leak would loop something like this:
template<>
void write<uint64_t>(char *dst, uint64_t src)
{
char *srcBytes = toBytes(src);
std::copy(srcBytes, srcBytes+8, dst);
delete [] srcBytes;
}
or using a smart pointer:
template<>
void write<uint64_t>(char *dst, uint64_t src)
{
std::unique_ptr<char[]> srcBytes(toBytes(src));
std::copy(srcBytes.get(), srcBytes.get()+8, dst);
}
Both use the std::copy stock algorithm which both accomplishes what you seem to want, while retaining the original result of toBytes for proper cleanup. Which you choose (or perhaps something entirely different still) I leave to you.
Best of luck.
These are a few cases where you will leak the memory where you used "new":
The function runs out of scope before you could delete it and there is no pointer to the allocated memory outside of the function.
You forget to delete where appropriate
You mix delete and delete []
Exception is caught between the use of "new" and "delete".
Even as a beginner, it's a good idea to get familiar with smart pointers.
I heard a lot of memory leak vulnerability, but I could not find a real work example of memory leak, could you provide a real work example of memory leak, maybe of some big open source project and explain the solution to me
thx.
It's really simple actually. In your main put:
char* c = new char[4];
Then exit. That's a memory leak. Any new that doesn't get followed by delete is a leak.
This answer has some good examples, but like my comment has said, it will be fairly hard to find a released application with a leak that an outside observer can look at and easily identify.
I am screaming, cursing and yelling everyday about code like this in our (huge) legacy code base:
// returns raw pointer with changing conventions who's the owner...
HelpFoo* Foo::GetFoo(Bar* pBar, OtherFoo* pFoo)
{
// all 'local' variables even those allocated on freestore declared
// and initialized in a large block at the beginning of the function/method
HelpFoo *A = new HelpFoo;
OtherHelpFoo *B, *C;
EvenMore *D = new EvenMore;
// and so on, these blocks can be huge...
// a complicated spaghetti code in here, with dozens of nested 'ifs'
if (/* some expression */) {
} else if (/* some other expression */) {
// and so on... then suddenly:
if (/* some other nested expression */) {
// I forgot that I've allocated other memory at the beginning...
return A;
}
}
// some miserably written logic here and suddenly
if (D) delete D; return A;
// call to some other function with cryptical name without any
// kind of knowledge what happens with the resource:
FooTakesReferenceToPointer(&A);
// suddenly returning something completely different
// what should I free, A, D...?
return C;
}
I tried to write in comments what the problems are. Clearly, forget about exceptions. The spaghetti code is so bad that nobody can tell what the logic actually is. Therefore it is really, really easy to forget to free memory and that happens very, very frequently. Solution 1: Throw away and rewrite everything. Solution 2: Keep spaghetti as it is, replace all newed resources by smart pointers and make_shared or make_unique, let compiler yell. Of course, first write a test suite (which didn't exist before) to guarantee the same (often screwed) behaviour for all possible sets of inputs (which are not documented).
EDIT
As james said this is undefined behaviourso no promises
You could do something like this:
#include <vector>
class Base
{
public:
Base()
{
baseData = new char [1024];
}
~Base()
{
delete [] baseData;
}
private:
char* baseData;
};
class Derived : public Base
{
public:
Derived()
{
derivedData = new char[1024];
}
~Derived()
{
delete [] derivedData;
}
private:
char* derivedData;
};
int main()
{
std::vector<Base*> datablocks;
datablocks.push_back(new Base());
datablocks.push_back(new Derived());
for(unsigned int i = 0; i < datablocks.size(); ++i)
{
delete datablocks[i];
}
datablocks.clear();
return 0;
}
The data in the Derived class wont be removed here since we are calling delete on a Base* and the Base class does not declare a virtual destructor.
A lot examples could be given here. Just allocate some memory and do not free it.
A good example for this would be the following:
char* pBuffer = new char[ 1024 ]; // or something else, dynamically allocated
// do something here
// now suppose, calling f() throws
f();
// do some other things
delete[] pBuffer;
When f() throws, if the exception is not caught, delete[] will never be executed. Thus, memory leak.
This is one of the best examples why smart pointers should be used.
Another example would be - a function, returning pointer to dynamically allocated memory. The user, often, may forget to free this memory. Something like:
char
char* f()
{
return new char[ 1024 ];
}
//...
// in some other function
char* pSomething = f();
// do some stuff here and return
Imagine you're processing network data and create polymorphic "message objects" based on the data:
while (true)
{
char buf[1024];
size_t len = read_from_network(buf, 1024); // fictitious, for demonstration only
Message * p = Message::Parse(buf, len); // allocates new, dynamic, concrete object
engine.process(p);
}
The engine object may chose to store the object somewhere and use it again later, and if nobody takes care of deleting it, you have a perfect leak.
While the other answers give enough hints, some 'real world' memory leaks which I have seen in our applications.
I don't remember if this was found before or after the release, but, I guess that doesn't matter.
void f()
{
BYTE* b = NULL;
f = open a file;
while (!f.end())
{
int size = getNextRecordSize(f);
b = new BYTE;
readNextRecord(f,b);
process record;
}
delete b;
}
Bit hard to detect this. The reviewers might take it for granted that the memory is deleted properly by seeing the delete call. However, it deletes only the memory allocated for the last record. Rest is leaked.
class A
{
public:
BYTE* get()
{
allocate a new buffer, copy the someData buffer and return that.
The client is expected to delete it
};
private:
BYTE* someData;
};
void f()
{
A a;
B.initialize(a.get()); // It is so convenient to use the pointer. It is not obvious from the function name
// that the result of get has to be deleted.
}
One example I often run across in our code is in image understanding functions, where a temporary 8bit memory is allocated, and never released (yeah, I know, when you do a new, do a delete right afterwards...)
unsigned char* dataToBeUsed = new unsigned char[imgsize];
memcpy(dataToBeUsed, original, imgsize);
// use and process the data here
return value;
The allocated memory is never released -> memory leak. Windows will kill the memory when the application is exited completely, but before that within the application that memory is just lost -> leaked.
A memory leak occurs when the programmer has the memory leak of forgetting to free allocated memory :-)
linebuffer = new char[4096];
/* do things */
/* forget to free memory */
Normally, if you cause a memory leak and then exit the program, it is not harmful, since the operating system normally frees the resources allocated by the program. The problem arises when your application runs for a long period of time (for example, a service). If your program causes memory leaks, then you will run out system's memory, unless the operating system has mechanisms to avoid that; in such case, it will terminate your program.
So, be careful and eat fish: it's very good for memory :-)
To give you a real-world example, a bit of googling turned up this memory leak in 389 Directory Server (a RedHat Open Source product).
Just lose the pointer to dynamically allocated memory:
void foo()
{
int *arr = new int[100];
}
pointer segfault problems...
I've been doing c++ for some weeks meanwhile but i ran again into that issue.
basically i have these classes given. I cant change them. I start with an instance of _ns3__importAuftragResponse kout;
class SOAP_CMAC _ns3__importAuftragResponse
{
public:
ns2__SOAPImportResult *return_;
...
class SOAP_CMAC ns2__SOAPImportResult
{
public:
bool *error;
int *numberOfIgnoreds;
....
My code needs to check for the numberOfIgnoreds
first approach
ns2__SOAPImportResult* imp_result;
imp_result = kout.return_;
int num;
num = *imp_result->numberOfIgnoreds;
or i use
ns2__SOAPImportResult imp_result;
imp_result = *(kout.return_);
int* num;
*num = *imp_result.numberOfIgnoreds;
I mostly get segmentation fault
I know generally what happens at runtime but cant come up with the correct ode. PLease help.
EDIT
made progress thx to your answer, Nawaz , but still need some understanding
ns2__SOAPImportResult * imp_ptr = new ns2__SOAPImportResult;
imp_ptr = kout.return_;
int * num = new (int);
// next line segfaults
*num = *imp_ptr->numberOfIgnoreds;
what's hard for me to understand is, how or why allocate memory for something that is already "there" as there is the member return_ of the object kout
So is it correct to say I need to allocate memory for the variable I assign it to (which is of same type of course)?
Most likely you've not allocated memory for the following members which you're using in the code you've quoted.
ns2__SOAPImportResult *return_; //in the class _ns3__importAuftragResponse
int *numberOfIgnoreds; //in the class ns2__SOAPImportResult
Other than this I don't see anything where things might go wrong!
Make sure you allocate memory for these members (and all other pointers in your program) before using them. You can use new to allocate memory. Or alternatively, you can use malloc() as well. Whatever you use, use it consistently, and deallocate the memory once you done, using delete or free() respectively!
This looks like gsoap. In that case you must use soap_malloc to allocate memory which you return.
For example on the FAQ page, you will find this example:
int ns__itoa(struct soap *soap, int i, char **a)
{ *a = (char*)soap_malloc(soap, 11);
sprintf(*a, "%d", i);
return SOAP_OK;
}
I'm having a tricky debugging issue, perhaps due to my lack of understanding about how c++ manages memory. The code is too long to post, but the essential setup is as follows:
global_var = 0;
int main() {
for(i = 0; i < N; ++i) {
ClassA a;
new ClassB(a); // seems to be problem!
}
}
For some N, global_var gets corrupted (is no longer 0). There is nothing in the constructors of ClassA or ClassB that mess with global_var.
Replacing new ClassB(a) with ClassB b(a) seems to solve the problem, although this doesn't allow me to do what I want (create a boost::ptr_vector with the new ClassB(a) instances).
Any ideas on what might be going wrong?
Update:
I'm really doing something like:
global_var = 0;
int main() {
boost::ptr_vector<ClassB> myobjects;
for(i = 0; i < N; ++i) {
ClassA a;
myobjects.push_back(new ClassB(a)); // seems to be problem!
}
}
Both create problems. But why is this a problem? Should I be doing something else to put a bunch of objects into a queue? I'm using myobjects it as the basis of a Command Pattern.
Update
`classB' looks like:
class ClassB {
public:
ClassB() {}
ClassB(ClassA a) : a_(a) {}
private:
ClassA a_;
}
ClassA is just a simple list initialization as well (in real life).
Problem?
Update
I believe this may have something to do with the fact that global_var is actually a complex matrix type and there may be issues with the way it allocates memory.
Memory in C++ is not automatically freed by default. The result of
new ClassB(a); // seems to be problem!
is being created on the heap. The address of the memory is not assigned to anything. Therefore one can't manually delete it like
ClassB* b = new ClassB(a); // creates a B, returns an address,
// and stores the address in b.
delete b; // deletes memory at address "b"
The failure to delete the memory may cause the heap to overflow into other regions of memory in your program, causing your global variable to be overwritten. This could happen without assigning the result of new to a variable, so long as its not deleted.
Does classA have a copy constructor? If so, what does it look like? If not, create a copy constructor in classA and see if that fixes the problem.
Other than that, try running your code in a debugger and see if you can pin-point when that global changes.
This is most probably a bug in one of the two constructors (ClassA or ClassB) which is overwriting the memory of global_var, or corrupting some other memory which eventually causes it to get overwritten.
I'd suspect something in Class A's copy constructor.
You can set a data write breakpoint on global_var to find out where it's being written.
In the MSVC debugger, set a breakpoint on the 'for' line. When it gets there, select "New Breakpoint->New Data Breakpoint..." from the Debug menu and enter the &global_var. Continue. The debugger will break the next time the variable is written.
gdb can do this too, but I've forgotten the syntax.
After much exploration, this behavior turned out to be due to a bug in the underlying class of global_var. There was a subtle bug in the way global and static memory allocation was being done.