c++ memory leak caused by vector of structs - c++

The memory leak caused by the line indicated. "pendingSendReqs.push_back(&f);" in the sendreq() method. I am new to c++ so I can't seem to figure out why the memory leak is occuring. The size of memory leaked is 16 bytes.
class Station {
struct Frame {
enum { Token, Data, Ack } type; // type of frame
unsigned int src; // source id
unsigned int dst; // destination id
unsigned int prio; // priority
} frame;
unsigned int stnId;
static unsigned int requests; // total send requests (if needed)
void data( Frame frame ); // pass frame
void main(); // coroutine main
Station *nextStation;
vector<Frame*> pendingSendReqs;
public:
Station( unsigned int id ) : stnId(id) { }
~Station() {
for (int i = 0; i < pendingSendReqs.size(); i++) {
delete pendingSendReqs.at(i);
cout << "~: " << pendingSendReqs.at(i) << endl;
}
}
//unsigned int getId() { return stnId; }
void setup( Station *nexthop ) { // supply next hop
//*nexthop is the object
nextStation = nexthop;
//cout << "size: " << sizeof(*nexthop) << endl;
}
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) { // store send request
Frame f;
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
}
void start(); // inject token and start
};

This is not a memory leak
pendingSendReqs.push_back(&f);
it is future undefined behaviour. You are storing the address of a local variable. Any attempt to de-reference one of those pointers outside of the scope of the function is undefined behaviour.
You have to ask yourself whether you really need a vector of pointers. If you don't know the answer to that, it is likely that you don't.

You're storing pointers to local variables, which will automatically get destroyed, inside the vector. This is illegal.
vector<Frame*> pendingSendReqs;
// this is a vector of pointers to struct and not a vector of structs
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) {
Frame f; // this automatic variable will get destroyed when sendreq returns
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
// because you're going to hold on to this address which will mean
// nothing when this function returns
}
The way you intend to do it is:
vector<Frame> pendingSendReqs;
and inside sendreq:
pendingSendReqs.push_back(f); // store the object's copy instead of it's address so that it outlives the life of this local

when
void sendreq( unsigned int round, unsigned int dst, unsigned int prio )
ends,
your vector pendingSendReqs will contain pointers to variables that have been eliminated ( because are local variable ), and will contain garbage, and will give you a crash.

Related

Why does 'new' fail in class initialization

win7
gcc 6.4.0
cygwin 2.9.0
the following code fails in function g_block during class initialization but not when used in main. The failure is in the 'for' loop when I attempt to initialize the code (initialization is a side issue here). In both cases allocation seems successful but when used in a class, I can't use the memory allocated.
# include <iostream>
# include <iomanip>
using namespace std;
typedef struct { // gsl allocation 'block' descritpoin
size_t size; // block bytes size
double* data; // pointer to the first byte of the block
} gsl_block;
typedef struct { // matrix definition
size_t size1; // number of rows
size_t size2; // number of columns
size_t tda; // number of elements in row (stride between rows)
double* data; // pointer to matrix[0][0]
gsl_block* block; // pointer to the gsl_matrix block
int owner; // 1: deallocation permitted
} gsl_matrix;
class X {
public:
inline static gsl_matrix& g_matrix(size_t row, size_t col)
{return g_matrix(row, col, g_block(row * col));};
static gsl_block& g_block(size_t size) {
double* ptr = new double(size);
cout << "size " << setw(5)<< size << " addr range "
<< hex << setfill('0') << ptr << " - " << (ptr + size*sizeof(double))
<< dec << setfill(' ') << endl;
for(size_t ndx = 0; ndx < size; ndx++) ptr[ndx] = 0.0;
return * new gsl_block{size, ptr};
};
static gsl_matrix& g_matrix(size_t row, size_t col, gsl_block& block) {
return * new gsl_matrix{row, col, col, block.data, &block, 0}; }
gsl_matrix& g_mat;
X() : g_mat(g_matrix(92, 92)) {}
}; // class X
int main(int argc, char** argv) {
gsl_matrix& mat = X::g_matrix(92, 92);
X* x = new X();
return 0;
}
double* ptr = new double(size);
This line creates a single double with the value size on the free store, and returns a pointer to it.
for(size_t ndx = 0; ndx < size; ndx++) ptr[ndx] = 0.0;
This line then invokes undefined behavior by attempting to write to memory that your program does not own.
You should really use std::vector instead of raw pointers. As your program stands, you have a significant potential to leak memory. If you made gsl_block::data a std::vector<double>, your classes would get proper copy and move semantics for free, and you wouldn't need to directly use new anywhere in your code.
EDIT:
Now that you've mentioned you're using GNU Scientific Library, you should probably just use the functions that library provides for allocating and freeing matricies: gsl_matrix_alloc and gsl_matrix_free. I would re-write your X class to just contain a std::unique_ptr with gsl_matrix_free as its deleter:
struct X
{
struct free_matrix
{
void operator()(gsl_matrix* mat)
{
gsl_matrix_free(mat);
}
};
std::unique_ptr<gsl_matrix, free_matrix> g_mat;
X(std::size_t rows, std::size_t cols)
: g_mat(gsl_matrix_alloc(rows, cols))
{}
};
You could even go further and completely wrap gsl_matrix in a more C++-like interface, with member functions that call gsl_matrix_get/gsl_matrix_set or gsl_matrix_pointer to provide simple access to the matrix elements.

Access violation when using int (*)[4] in structure

I define arrays of integers in my code:
unsigned int tara[1024][3];
unsigned int data[1024][4];
I have storage structure, that allows me to pass them as void*:
struct storage {
unsigned int (*data)[4];
unsigned int (*tara)[3];
};
This is my use of structure above:
int main() {
unsigned int tara[1024][3];
unsigned int data[1024][4];
storage but_data;
but_data.data = data;
but_data.tara = tara;
tara_button.setCallback(taraButtonCallback, (void*)&but_data); //Some UI class
while(true); //The program
return 0;
}
In callback, this is how I try to access data:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data_struct = (storage*)but_data;
int max = -5;
int max_value = 0;
cout<<data_struct->data[0][0]<<'\n'; //!!ERROR!!
return true;
}
This is runtime error I get:
Unhandled exception at 0x00394f1c in OpenCV.exe: 0xC0000005: Access violation reading location 0x00000005.
Edit:
The problem is not related to to where is the but_data defined! This callback works:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data = (storage*)but_data;
set_tara(data->data, data->tara, *data->mat);
*(data->tara_set) = true;
return true;
}
void set_tara(unsigned int data[][4], unsigned int tara[][3], Mat &UI_bot)
{
UI_bot = Scalar(0, 0, 0);
for(int x=0; x<cam_frame_width; x++) {
tara[x][0]=data[x][0];
tara[x][1]=data[x][1];
tara[x][2]=data[x][2];
}
}
At the time the callback is called, but_data is already destroyed:
storage but_data;
It is allocated locally, which means that its lifetime is limited with the end of current function. After the function is completed, it ceases to exist, and the callback uses a dangling pointer.
Just assign it to a variable and print it
int taraButtonCallback(void* but_data)
{
struct storage* data = ( struct storage*)but_data;
int max = -5;
int max_value = 0;
int val = data->data[0][0];
cout <<val ; //!!works!!
return 0;
}
I think cout is unable to handle [][] in this case .. I am not sure why someone can enlighten both of us
You could try allocating the variable storage but_data like this:
storage *but_data = new storage;
effectively creating a variable with infinite lifetime.
Than you would define your callback function a bit differently (because you already have a pointer, so you do not need the address of the variable) - like this:
tara_button.setCallback(taraButtonCallback, (void*)but_data);
//note the lack of '&' sign before the but_data variable name
Just don't forget to delete it after you no longer need it!
delete but_data;

How to cast from char pointer to custom object pointer

I'm using leveldb to store key-value pairs of integer and MyClass objects. Actually, a key can contain more then one of theses objects.
The problem I have appears when retrieving the data from the database. It compiles, however the values of the MyClass members are not the one I put into the database.
std::string value;
leveldb::Slice keySlice = ANYKEY;
levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value);
The std::string value1 can now contain only one MyClass object or more. So how do I get them?
I already tried the following which didn't work;
1.) directly typecasting and memcpy
std::vector<MyClass> vObjects;
MyClass* obj = (MyClass*)malloc( value.size());
memcpy((void*)obj, (void*) (value.c_str()), value.size());
MyClass dummyObj;
int numValues = value.size()/sizeof(MyClass);
for( int i=0; i<numValues; ++i) {
dummyObj = *(obj+i);
vObjects.push_back(dummyObj);
}
2.) reinterpret_cast to void pointer
MyClass* obj = (MyClass*)malloc( value.size());
const void* vobj = reinterpret_cast<const void*>( value.c_str() );
int numValues = value.size()/sizeof(MyClass);
for( int i=0; i<numValues; ++i) {
const MyClass dummyObj = *(reinterpret_cast<const MyClass*>(vobj)+i);
vObjects.push_back(dummyObj);
}
MyClass is a collection of several public members, e.g. unsigned int and unsigned char and it has a stable size.
I know that there are similar problems with only one object. But in my case the vector can contain more then one and it comes from the leveldb database.
EDIT: SOLUTION
I wrote (de)serialization method for MyClass which then made it working. Thanks for the hint!
void MyClass::serialize( char* outBuff ) {
memcpy(outBuff, (const void*) &aVar, sizeof(aVar));
unsigned int c = sizeof(aVar);
memcpy(outBuff+c, (const void*) &bVar, sizeof(bVar));
c += sizeof(bVAr);
/* and so on */
}
void MyClass::deserialize( const char* inBuff ) {
memcpy((void*) &aVar, inBuff, sizeof(aVar));
unsigned int c = sizeof(aVar);
memcpy((void*) &aVar, inBuff+c, sizeof(aVar));
c += sizeof(aVar);
/* and so on */
}
The get method is as follows (put analogously):
int getValues(leveldb::Slice keySlice, std::vector<MyObj>& values) const {
std::string value;
leveldb::Status status = levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value);
if (!status.ok()) {
values.clear();
return -1;
}
int nValues = value1.size()/sizeof(CHit);
MyObj dummyObj;
for( int i=0; i<nValues; ++i) {
dummyObj.deserialize(value.c_str()+i*sizeof(MyObj));
values.push_back(dummyObj);
}
return 0;
}
You have to serialize your class... otherwise, you're just taking some memory and writing it in leveldb. Whatever you get back is not only going to be different, but it will probably be completely useless too. Check out this question for more info on serialization: How do you serialize an object in C++?
LevelDB does support multiple objects under one key, however, try to avoid doing that unless you have a really good reason. I would recommend that you hash each object with a unique hash (see Google's CityHash if you want a hashing function) and store the serialized objects with their corresponding hash. If your objects is a collection in itself, then you have to serialize all of your objects to an array of bytes and have some method that allows you to determine where each object begins/ends.
Update
A serializable class would look something like this:
class MyClass
{
private:
int _numeric;
string _text;
public:
// constructors
// mutators
void SetNumeric(int num);
void SetText(string text);
static unsigned int SerializableSize()
{
// returns the serializable size of the class with the schema:
// 4 bytes for the numeric (integer)
// 4 bytes for the unsigned int (the size of the text)
// n bytes for the text (it has a variable size)
return sizeof(int) + sizeof(unsigned int) + _text.size();
}
// serialization
int Serialize(const char* buffer, const unsigned int bufferLen, const unsigned int position)
{
// check if the object can be serialized in the available buffer space
if(position+SerializableSize()>bufferLen)
{
// don't write anything and return -1 signaling that there was an error
return -1;
}
unsigned int finalPosition = position;
// write the numeric value
*(int*)(buffer + finalPosition) = _numeric;
// move the final position past the numeric value
finalPosition += sizeof(int);
// write the size of the text
*(unsigned int*)(buffer + finalPosition) = (unsigned int)_text.size();
// move the final position past the size of the string
finalPosition += sizeof(unsigned int);
// write the string
memcpy((void*)(buffer+finalPosition), _text.c_str(), (unsigned int)_text.size());
// move the final position past the end of the string
finalPosition += (unsigned int)_text.size();
// return the number of bytes written to the buffer
return finalPosition-position;
}
// deserialization
static int Deserialize(MyClass& myObject,
const char* buffer,
const unsigned int buffSize,
const unsigned int position)
{
insigned int currPosition = position;
// copy the numeric value
int numeric = *(int*)(buffer + currentPosition);
// increment the current position past the numeric value
currentPosition += sizeof(int);
// copy the size of the text
unsigned int textSize = *(unsigned int*)(buffer + currentPosition);
// increment the current position past the size of the text
currentPosition += sizeof(unsigned int);
// copy the text
string text((buffer+currentPosition), textSize);
if(currentPosition > buffSize)
{
// you decide what to do here
}
// Set your object's values
myObject.SetNumeric(numeric);
myObject.SetText(text);
// return the number of bytes deserialized
return currentPosition - position;
}
};

something strange with posix threads in C++

I face a strange error with pthreads in C++, I try to run this code:
typedef struct
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
}param;
pthread_t clientThread;
param sentParam ;
sentParam.clienAddr = clientAddress;
sentParam.clientLength= client_info;
sentParam.message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam );
cout <<"i: "<<i<<endl;
the function which be called
void* handleClientRequestRead(void* params)
{
// cout<<"params: "<< ;
string msg = (( param *)(params))->message;
}
When I try to print msg it's empty. Any help will be appreciated
My guess is that when handleClientRequestRead gets called sentParam has already gone out of scope and its memory has been reused for other purposes.
You should allocate memory for your parameters in a location that will still be valid when you'll access it from the thread (e.g. on the heap, keeping in mind that you must free it when you don't need it anymore; a valid help can be shared_ptr).
By the way, in C++ you don't need the typedef trick for structs.
I agree with #Matteo above:
struct param
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
};
void someFunction()
{
static int sentCount = 0;
static param sentParam[10];
// ^^^^^^ Notice these are static
// Thus they will last the length of the program.
// An alternative is to dynamically creation but then you have
// to destroy them at some point.
//
if (count >= 10)
{ throw std::runtime_error("Too many threads");
}
// If you want to keep more than 10 or use a dynamic number
// then use a std::list, NOT a std::vector
sentParam[sentCount].clienAddr = clientAddress;
sentParam[sentCount].clientLength= client_info;
sentParam[sentCount].message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
pthread_t clientThread;
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam[sentCount] );
cout <<"i: "<<i<<endl;
if (i == 0)
{
++sentCount;
}
}

Stack memory allocation

It is being said that local variable will be allocated and deallocated automatically when function ends in C/C++.
According to my understanding, when having been deallocated, the value held by local variable also be destroyed!!! Please correct me if i'm wrong
Consider following code:
void doSomething(int** num)
{
int a = 10;
*num = &a;
} // end of function and a will be destroyed
void main()
{
int* number;
doSomething(&number);
cout << *number << endl; // print 10 ???
}
Could anybody clarify for me?
You are correct. your cout may or may NOT print 10. It will invoke undefined behavior.
To make a bit more of a note, try running the following code under your compiler with no optimizations enabled.
#include <iostream>
using namespace std;
void doSomething(int** num)
{
int a = 10;
*num = &a;
}
void doSomethingElse() {
int x = 20;
}
int main()
{
int* number;
doSomething(&number);
doSomethingElse();
cout << *number << endl; // This will probably print 20!
}
In this case, the integer a is on the stack. You are returning the address of that variable to the main program. The value at that address location after the call is undefined. It is possible in some situations that it could print 10 if that portion of the stack was not overwritten (but you certainly would not want to rely on it).
The content of the memory isn't actually destroyed.
For this case, num will point to a location which isn't being allocated for any variable, but it will hold it's content, which was set to 10.
The memory being pointed to has been released back to the system. That means that it will hold whatever value it had until the system assigns that block of memory to another variable and it gets overridden with a value.
Local variables are released when they go out of scope. If you are trying to return a value using an out parameter to a function:
void doSomething(int** num)
{
int* a = new int;
*a = 10;
*num = a;
}
int main()
{
int* number = 0;
doSomething(&number);
std::cout << *number << std::endl; // print 10 ???
if (number) delete number;
}
Though, for something this simple, you are better off just doing this:
int doSomething()
{
return 10;
}
int main()
{
std::cout << doSomething() << std::endl;
}