Bad_alloc Exception in function in C++ - c++

Hi I am new in C++ programming, I have a function that return short*
My Function Code is
This function executes thousands of time because of this bad_alloc at memory location in generated so can anyone tell me how to solve this.
Code where getoneframe function call
short *myData = NULL;
sock.SetCameraIP(m_destination_IP, m_destination_port);
m_startCamFlag = sock.StartCamera();
if (!m_startCamFlag)
{
std::cout << "Unable to Start the Camera" << std::endl;
}
std::thread acquiringThread(callReceiveFunction, sock);
acquiringThread.detach();
while (flag)
{
myData = sock.GetOneFrame();
ImageShow(myData);
Sleep(15);
if (GetAsyncKeyState(VK_ESCAPE))
{
flag = false;
}
}

Your function allocates dynamic memory in the line
short *m_returnframeBuffer = new short[BYTE_PER_FRAME];
and returns the pointer to the calling function as
return m_returnframeBuffer;
It sounds like the calling function does not deallocate the memory, which causes bad_alloc to be thrown when the function is called thousands of times.
Make sure that the calling function deallocates the memory after it is done using it.
short* buffer = SomeCameraObject.GetOneFrame();
// Use buffer
// Deallocate memory.
delete [] buffer;
Update the while loop in the calling function to:
while (flag)
{
myData = sock.GetOneFrame();
ImageShow(myData);
Sleep(15);
if (GetAsyncKeyState(VK_ESCAPE))
{
flag = false;
}
// Add this line
delete [] myData;
}

while (m_bufferIndex1 != MAX_BYTE_PER_FRAME)
{
m_myChar1 = m_frameBuffer1[m_bufferIndex1++];
m_myChar2 = m_frameBuffer1[m_bufferIndex1++];
value = (m_myChar1 << 8) | m_myChar2;
m_returnframeBuffer[m_bufferIndex2++] = value;
}
m_bufferIndex1 is getting incremented twice. So, if m_bufferIndex1 is MAX_BYTE_PER_FRAME-1, it will enter the loop and gets incremented twice and the while loop never breaks. Add another check there before incrementing second time

Related

Exception thrown at 0x0037A5C2 project.exe: 0xC0000005: Access violation writing location 0xDDDDDDDD at the end of the program

I have encountered this runtime exception at the very end of the program by simply creating an instance of the specified class, so I presume the issue lies with either the constructor, copy constructor, copy assignment operator or destructor. I have read up on and followed the rule of three to the extent of my limited cpp knowledge.
Source.cpp
#include "Header.h"
#include <iostream>
using namespace std;
int main() {
string command = "CREATE TABLE table_name IF NOT EXISTS ((column_1_name,type,default_value), (column_2_name,type,default_value))";
string columns[20] = { "column_1_name,type,default_value", "column_1_name,type,default_value" };
string commandData[9] = { "table_name", "IF NOT EXISTS" };
CommCREATETABLE comm(command, columns, commandData, 2, 2);
}
Relevant code from Header.h
class CommCREATETABLE {
string fullCommand = "";
string* columns = nullptr;
string* commandData = nullptr;
string tableName = "";
int nrOfColumns = 0;
int nrOfElements = 0;
bool valid = false;
Constructor:
CommCREATETABLE(string command, string* columns, string* commandData, int nrOfRows, int nrOfElements) {
this->setNrOfColumns(nrOfRows);
this->setNrOfElements(nrOfElements);
this->setCommand(command);
this->setColumns(columns);
this->setCommandData(commandData);
this->valid = checkInput(this->commandData, this->columns);
this->setTableName(commandData[0]);
}
Copy constructor, copy assignment operator, destructor:
CommCREATETABLE(const CommCREATETABLE& comm) {
this->setNrOfColumns(comm.nrOfColumns);
this->setNrOfElements(comm.nrOfElements);
this->setCommand(comm.fullCommand);
this->setColumns(comm.columns);
this->setCommandData(comm.commandData);
this->setTableName(comm.tableName);
this->valid = comm.valid;
}
~CommCREATETABLE() {
if (this->columns != nullptr) {
delete[] this->columns;
}
if (this->commandData != nullptr) {
delete[] this->commandData;
}
}
CommCREATETABLE& operator=(const CommCREATETABLE& comm) {
this->setCommand(comm.fullCommand);
this->setColumns(comm.columns);
this->setCommandData(comm.commandData);
this->setTableName(comm.tableName);
this->setNrOfColumns(comm.nrOfColumns);
this->setNrOfElements(comm.nrOfElements);
this->valid = checkInput(this->commandData, this->columns);
return *this;
}
The only setters that deal with dynamic memory allocation are the following:
void setColumns(const string* columns) {
if (this->nrOfColumns >= 0) {
this->columns = new string[this->nrOfColumns];
memcpy(this->columns, columns, this->nrOfColumns * sizeof(string));
}
else throw EmptyCommandException();
}
void setCommandData(const string* commandData) {
if (this->nrOfElements >= 0) {
this->commandData = new string[this->nrOfElements];
memcpy(this->commandData, commandData, this->nrOfElements * sizeof(string));
}
else throw EmptyCommandException();
}
At a quick glance I would say the issue is in your setColumns and setCommandData functions. (I might of course be wrong, I did not try to run the code you presented nor the changes I made -- so there might also be a typo somewhere.)
There you use memcpy to copy the strings into your class. However, internally a C++ string holds a pointer to the actual string, so using memcpy actually only copies that pointer. As a result, once the original string gets deleted, the pointer you copied into your class is no longer valid (as the memory has already been freed). As a result, once your class also gets deleted it attempts to delete memory that has already been freed. That is probably where your error comes from.
In fact, if you added lines to your program where you tried to manipulate your class (after the original input strings have already been deleted), the problem would present itself even sooner, as you would be accessing memory that has already been freed. This would lead to undefined behaviour, which typically ends with a crash at some point.
A quick fix would be to change the way you copy the data, by using = for each string (in that way copying the actual strings into a new location in memory, rather than copying the pointer).
void setColumns(const string* columns) {
if (this->nrOfColumns > 0) { // Creating an array of size 0 is also not a good idea.
this->columns = new string[this->nrOfColumns];
for (int i = 0; i < nrOfColumns; i++) { // You don't need this everywhere.
this->columns[i] = columns[i];
// I don't think naming things the exact same way is good practice.
}
}
else throw EmptyCommandException();
}
void setCommandData(const string* commandData) {
if (this->nrOfElements > 0) { // Creating an array of size 0 is also not a good idea.
this->commandData = new string[this->nrOfElements];
for (int i = 0; i < nrOfElements; i++) { // You don't need this everywhere.
this->commandData[i] = commandData[i];
// I don't think naming things the exact same way is good practice.
}
}
else throw EmptyCommandException();
}
Alternatively, if you want to avoid making copies you should look into move, but I would suggest against this for the time being, if you are still learning. You'll get there soon enough.

Memory error on displaying opencv matrix

I made a class consuming a serialized Opencv matrix. It is working fine and the Matrix is deserialized. If I try to display it inside the method of the class using the imshow method, it will work perfectly well, displaying without error. However, I am passing a parameter reference to a Matrix pointer from my main function in order to further process this matrix. When I try to display it in the main, I end up with a segmentation fault.
The weird part is that if I try to display the matrix in both the class method and the Main, I will end up with two windows working fine (sometimes I will get a segmentation fault but most of the time it works good).
If I remove the displaying code from the method, I won't even be able to display one frame before getting a segmentation fault.
I have tried using a shared_ptr, passing a pointer to the pointer instead of a reference, or even simply returning the value.
My code is kind of messy but the main aim of it is testing.
Here is the code of the method :
void VideoConsumer::getVideoFrame(cv::Mat* &mat) {
Message msg = _consumer->poll();
mat = NULL;
if(!msg) {
cerr << "No message received" << endl;
return;
}
if(msg.get_error()) {
if(!msg.is_eof()) {
cerr << "[+] Received error notification: " << msg.get_error() << endl;
}
return;
}
Document document;
string jsonPayload = "";
for(auto i=msg.get_payload().begin(); i != msg.get_payload().end();i++) {
jsonPayload += *i;
}
document.Parse(jsonPayload.c_str());
if(document.HasMember("rows") && document.HasMember("cols") && document.HasMember("data")) {
int rows = document["rows"].GetInt();
int cols = document["cols"].GetInt();
int type = document["type"].GetInt();
string data = document["data"].GetString();
std::vector<BYTE> decodedBytes = base64_decode(data);
stringstream ss;
for(int i=0;i< decodedBytes.size(); i++) {
ss << decodedBytes[i];
}
string decoded_data = ss.str();
cout << "Constructed string" << endl;
mat = new cv::Mat(rows,cols,type,(void *)decoded_data.data());
/*cv::imshow("test",*mat);
while(cv::waitKey(10) != 27)*/ //This is where it is displayed
return;
} else {
return;
}
}
And the code in the main :
...
if(parser.has("stream")) {
VideoConsumer consumer("localhost:9092","video-stream-topic","testId2");
consumer.setConsumer();
while(1) {
Mat *frame = NULL;
consumer.getVideoFrame(frame);
if(frame == NULL) {
cout << "Null frame" << endl;
continue;
}
if(!frame->empty() && frame->rows > 0 && frame->cols > 0) {
imshow("Test",*frame);
waitKey(10);
frame->release();
}
}
}
I am completely out of ideas and have tried every single thing I knew or found on my researches.
EDIT : Added frame->release() in order to free the allocation, still same issue.
There is a problem in your matrix initialization... Specifically in here:
mat = new cv::Mat(rows,cols,type,(void *)decoded_data.data());
That one is this constructor
Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
which in the documentation says the following about the *data parameter
data Pointer to the user data. Matrix constructors that take data and
step parameters do not allocate matrix data. Instead, they just
initialize the matrix header that points to the specified data, which
means that no data is copied. This operation is very efficient and can
be used to process external data using OpenCV functions. The external
data is not automatically deallocated, so you should take care of it.
This means that as soon it goes out of scope (the function exits) the string which you created (decoded_data) will exit and the data will be deallocated by the string, and then your cv::Mat will have a reference to a data that is not valid anymore...
You can always initialize the matrix with something like
cv::Mat(rows,cols,type)
and then use something like std::memcpy or similar to copy the data to the mat.data member. Actually, AFAIK it is not needed to pass byte to string and then to mat which is casted to void and then to uchar....
try something like:
mat = cv::Mat(rows,cols,type);
std::memcpy(&decodedBytes[0], mat.data, decodedBytes.size());
Just a small warning for this solution, you need to do a check that decodedBytes is not empty and that mat.data has enough space to receive all the contents of decodedBytes. To do this check just make sure:
// size in bytes to copy == size of the allocated data of mat in bytes
decodedBytes.size() == (mat.elemSize() * mat.rows * mat.cols)
A couple of remarks more that may not be an issue now, but may bite you later:
Do not use cv::Mat pointers... The behaviour of cv::Mat is already like a smart pointer.
Beware of the casting/copy of data from sign to unsign and viceversa :) I think now it is done correctly, but this may become a problem later.

free() detecting heap corruption

When using Visual Studio 2013 heap corruption is detected on calling free().
It is not detected on Linux.
My code seems to run fine until it hits the free function. I call free many times, but in one specific instance, it causes a window to pop up saying HEAP CORRUPTION DETECTED.
I've allocated memory to store pointers to strings(words) for two sets of words. For the first set of words, upon freeing them, no error message is given.
For the second set of words, upon freeing them, the error message pops up.
Here is the code for the first set of words, I made an array of words called arrayFictionary. The function takes a pointer to the array of pointers and adds on new words. No error message is given upon freeing(arrayFictionary).
void ConvertFictionary(char*** parrayFictionary, char* fictionary) {
char * pTemp = 0;
int32_t count = 1;
// put first fictionary word into an array
if(!(pTemp=strtok(fictionary, "\n"))) {//if the dictionary end is reached,
(*parrayFictionary)[count-1] = pTemp; // exit while loop
goto skipD;
}
*parrayFictionary = (char**) realloc(*parrayFictionary, (count + 1)*sizeof(char*));
(*parrayFictionary)[count-1] = pTemp;
count++;
while(1) {// put fictionary words into an array, exit when done
if(!(pTemp=strtok(NULL, "\n"))) {//if the dictionary end is reached,
(*parrayFictionary)[count-1] = pTemp; // exit while loop
break;
}
*parrayFictionary = (char**) realloc(*parrayFictionary, (count + 1)*sizeof(char*));
(*parrayFictionary)[count-1] = pTemp;
count++;
}
skipD:
return;
}
Here is the code for allocating an array for my second set of words called arrayFarticle. Same method is used with slight differences. Error message results upon calling free(arrayFarticle).
void ConvertFarticle(char*** parrayFarticle, char* farticle)
{
char * pTemp = 0;
int32_t count = 1;
// put first farticle word into an array
if(!(pTemp=strtok(farticle, "0123456789.,;: '\"\n!##$%%^&*()_-+=|\\[]{} <>?/~`’"))) //if the farticle end is reached, exit while loop
{
(*parrayFarticle)[count-1] = pTemp;
goto skipA;
}
if(strlen(pTemp)>=2)
{
*parrayFarticle = (char**) realloc(*parrayFarticle, sizeof(char*)*count + sizeof(char*)*2);
(*parrayFarticle)[count-1] = pTemp;
count++;
}
while(1) // put farticle words into an array, exit when done
{
if(!(pTemp=strtok(NULL, "0123456789.,;: '\"\n!##$%%^&*()_-+=|\\[]{}<>?/~`’"))) //if the farticle end is reached, exit while loop
{
(*parrayFarticle)[count-1] = pTemp;
break;
}
if(strlen(pTemp)>=2)
{
*parrayFarticle = (char**) realloc(*parrayFarticle, sizeof(char*)*count + 1);
(*parrayFarticle)[count-1] = pTemp;
count++;
}
}
skipA:
return;
}
I honestly don't know what's going on. I made sure that arrayFarticle isn't being written past its allocated limit.
Your last call to realloc results in *parrayFarticle pointing to a block with an odd (in the mathematical sense) size, and (quite likely) too small.

access violation reading location in c++

I have a thread which reads multicast data and updates certain data structures
and another thread which is handled by chai 3d library
when I just run my library code it works fine.
when I run y thread also
I get access violation in one of the routine inside the chai3d code.
my thread code
unsigned int __stdcall ThreadFunc(void* data)
{
char *timeOld;
int ID;
while(1)
{
char *position = _com_util::ConvertBSTRToString(cpi->getData());
ID = cpi->getMulticastDataID();
char* timeNew = _com_util::ConvertBSTRToString(cpi->getTime());
if(timeFirst == true)
{
timeOld = new char[strlen(timeNew) + 1];
strcpy(timeOld,timeNew);
timeFirst = false;
}
if((strcmp(timeNew,timeOld) != 0) && (AddItselToList == true) && ( ID != 99))
{handlePacket(position,ID);
strcpy(timeOld,timeNew);}
delete[] position;
delete[] timeNew;
}
delete[] timeOld;
}
cpi is a pointer to com c# object where getdata, gettime return strings and getmulticastid returns int.
is there something worn with my thread code?
_beginthreadex(NULL,0,ThreadFunc,NULL,0,NULL);
delete[] position and timeNew before the closing brace of the while loop. delete[] timeOld before the closing brace of ThreadFunc. Also, are you sure timeOld is long enough to copy timeNew into it? This may explain your access violation.

passing integer array in thread function

I am working on multiple producer and Single consumer problem.I wanted to pass Thread like 1,2,3 in the thread function so that individual thread can be named based on these number.
But the program is crashing after count 7 while creating thread.I think problem is due to
variable nThreadNo;
if i limit the count less than 7 it works fine.but if i make count more than this it crashes.
void CEvent1Dlg::CreateProducerThreads()
{
try
{
nThreadNo = new int20];
memset(nThreadNo,0,20);
if (nThreadNo ==NULL) return;
}catch(...)
{
MessageBox(_T("Memory allocation Failed"),_T("Thread"),1);
return ;
}
int i = 0;
for ( i = 0;i<20;i++)
{
//nThreadNo = i+1;
nThreadNo[i] = i+1;
hWndProducer[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProducerThrdFunc,(void*)(nThreadNo+i),0,&dwProducerThreadID[i]);
if (hWndProducer[i] == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
}
//WaitForMultipleObjects(20,hWndProducer,TRUE,INFINITE);
}
DWORD WINAPI ProducerThrdFunc ( LPVOID n )
{
int *nThreadNo = (int*)n;
char chThreadNo[33];
memset(chThreadNo,0,33);
while(1)
{
itoa(*nThreadNo,chThreadNo,10);
char* pMsg1 = new char[100];
char* pMsg2 = new char[100];
memset(pMsg1,0,100);
memset(pMsg2,0,100);
strcpy(pMsg1,"Producer ");
strcat(pMsg1," Thread No:");
strcat(pMsg1,chThreadNo);
if (stThreadInfoProd.pEventQueue->AddTail(pMsg1)==TRUE)
{
strcpy(pMsg2,"Producer ");
strcat(pMsg2," Thread No:");
strcat(pMsg2,chThreadNo);
strcat(pMsg2," Added the Msg");
}
else
{
strcpy(pMsg2,"Producer ");
strcat(pMsg2," Thread No:");
strcat(pMsg2,chThreadNo);
strcat(pMsg2,"failed to Add the Msg");
}
PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg2,0);
strcat(pMsg1," Adding Msg:");
//PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg2,0);
Sleep(3000);
}
return 0;
}
You are zeroing out the first 20 bytes of nThreadNo, not the first 20 * sizeof(int) bytes as you should be doing.
There are other arrays you are indexing into in this code: hWndProducer, dwProducerThreadID. Are there enough elements in those as well?
The CreateThread call is passing the integer value, but the thread function itself is treating it as a pointer to integer. Rather than this:
int *nThreadNo = (int*)n;
It should probably be:
int nThreadNo = (int)n;
Edit: I looked more closely at the call and I do see that it is passing an integer pointer. However, that value is stack data, which may not exist by the time the thread tries to read it. So it should probably just pass the integer value: (void*)(nThreadNo[i])
This line
if (nThreadNo ==NULL) return;
is worthless.
The new operator in modern C++ doesn't return NULL on failure, it throws a std::badalloc exception, but even if you were using an allocator that returns NULL to indicate failure, it's too late to detect it, you're already passed the NULL pointer to memcpy.