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.
Related
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
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.
I am currently working on a project where I have to build a shell for a C++ dll, so a new C# GUI can use its functions.
However I got the following problem, in the C++ portion I have to create a new thread for specific reasons, and I want to pass an int array to the new thread.
Note that the values assigned to the array in the function in which this happens are gained from the C# portion of the code.
__declspec( dllexport ) void CreateReportPane(int &id, int &what)
{
DWORD threadId;
int iArray[2] = { id, what};
HANDLE hThread = CreateThread( NULL, 0, CreateReportPaneThread, iArray, 0, &threadId);
if (hThread == NULL)
{
ExitProcess(3);
}
}
The problem arises in the new thread, I can reliably fetch the first value out of the array, but the 2nd value seems to be released, here is the code on the other side.
DWORD WINAPI CreateReportPaneThread(LPVOID lparam)
{
int id, what;
id = *(( int * )lparam);
what = *(((int *)lparam)+1) ;
CreateReportPaneOriginal(id, what);
return 0;
}
Is there any way to prevent the values in the array from getting released while not holding the original thread captive?
A big thank you in advance
int iArray[2] = { id, what};
HANDLE hThread = CreateThread(...,CreateReportPaneThread, iArray, ...);
The problem is that iArray is a local array which means this gets destroyed when the function CreateReportPane() returns. So what CreateReportPaneThread() refers to doesn't exist. You get the first value just by chance. There is no such guarantee that you would get even the first value.
Use dynamic array:
int * iArray = new int[2];
iArray[0] = id;
iArray[1] = what;
HANDLE hThread = CreateThread(...,CreateReportPaneThread, iArray, ...);
Remember to write deallocate the array once you're done with it in CreateReportPaneThread:
DWORD WINAPI CreateReportPaneThread(PVOID *data)
{
int *array = static_cast<int*>(data);
int id = array[0], what = array[1];
delete []array; //MUST DO IT to avoid memory leak!
//rest of your code
}
Dynamically allocate the array to prevent the array going out of scope when CreateReportPane() exits:
int* iArray = new int[2];
iArray[0] = id;
iArray[1] = what;
otherwise the thread is accessing an array that is no longer valid, which is undefined behaviour. The thread routine CreateReportPaneThread() must then delete[] the array when it is no longer required (note the use of delete[] and not delete).
I'm trying to fix this problem which seems like I am accessing at an out of range index, but VS fails to stop where the error occurred leaving me confused about what's causing this.
The Error:
Debug Assertion Failed! Program: .... File: c:\program files\microsoft visual studio 10.0\vc\include\vector Line: 1440 Expression: String subscript out of range
What the program does:
There are two threads:
Thread 1:
The first thread looks (amongst other things) for changes in the current window using GetForegroundWindow(), the check happens not on a loop but when a WH_MOUSE_LL event is triggered. The data is split into structs of fixed size so that it can be sent to a server over tcp. The first thread and records the data (Window Title) into an std::list in the current struct.
if(change_in_window)
{
GetWindowTextW(hActWin,wTitle,256);
std::wstring title(wTitle);
current_struct->titles.push_back(title);
}
Thread 2:
The second thread is called looks for structs not send yet, and it puts their content into char buffers so that they can be sent over tcp. While I do not know exactly where the error is, looking from the type of error it was to do either with a string or a list, and this is the only code from my whole application using lists/strings (rest are conventional arrays). Also commenting the if block as mentioned in the code comments stops the error from happening.
BOOL SendStruct(DATABLOCK data_block,bool sycn)
{
[..]
int _size = 0;
// Important note, when this if block is commented the error ceases to exist, so it has something to do with the following block
if(!data_block.titles.empty()) //check if std::list is empty
{
for (std::list<std::wstring>::iterator itr = data_block.titles.begin(); itr != data_block.titles.end() ; itr++) {
_size += (((*itr).size()+1) * 2);
} //calculate size required. Note the +1 is for an extra character between every title
wchar_t* wnd_wbuffer = new wchar_t[_size/2](); //allocate space
int _last = 0;
//loop through every string and every char of a string and write them down
for (std::list<std::wstring>::iterator itr = data_block.titles.begin(); itr != data_block.titles.end(); itr++)
{
for(unsigned int i = 0; i <= (itr->size()-1); i++)
{
wnd_wbuffer[i+_last] = (*itr)[i] ;
}
wnd_wbuffer[_last+itr->size()] = 0x00A6; // separator
_last += itr->size()+1;
}
unsigned char* wnd_buffer = new unsigned char[_size];
wnd_buffer = (unsigned char*)wnd_wbuffer;
h_io->header_w_size = _size;
h_io->header_io_wnd = 1;
Connect(mode,*header,conn,buffer_in_bytes,wnd_buffer,_size);
delete wnd_wbuffer;
}
else
[..]
return true;
}
My attempt at thread synchronization:
There is a pointer to the first data_block created (db_main)
pointer to the current data_block (db_cur)
//datablock format
typedef struct _DATABLOCK
{
[..]
int logs[512];
std::list<std::wstring> titles;
bool bPrsd; // has this datablock been sent true/false
bool bFull; // is logs[512] full true/false
[..]
struct _DATABLOCK *next;
} DATABLOCK;
//This is what thread 1 does when it needs to register a mouse press and it is called like this:
if(change_in_window)
{
GetWindowTextW(hActWin,wTitle,256);
std::wstring title(wTitle);
current_struct->titles.push_back(title);
}
RegisterMousePress(args);
[..]
//pseudo-code to simplify things , although original function does the exact same thing.
RegisterMousePress()
{
if(it_is_full)
{
db_cur->bFull= true;
if(does db_main exist)
{
db_main = new DATABLOCK;
db_main = db_cur;
db_main->next = NULL;
}
else
{
db_cur->next = new DATABLOCK;
db_cur = db_cur->next;
db_cur->next = NULL;
}
SetEvent(eProcessed); //tell thread 2 there is at least one datablock ready
}
else
{
write_to_it();
}
}
//this is actual code and entry point of thread 2 and my attempy at synchronization
DWORD WINAPI InitQueueThread(void* Param)
{
DWORD rc;
DATABLOCK* k;
SockWClient writer;
k = db_main;
while(true)
{
rc=WaitForSingleObject(eProcessed,INFINITE);
if (rc== WAIT_OBJECT_0)
{
do
{
if(k->bPrsd)
{
continue;
}
else
{
if(!k)
{break;}
k->bPrsd = TRUE;
#ifdef DEBUG_NET
SendStruct(...);
#endif
}
if(k->next == NULL || k->next->bPrsd ==TRUE || !(k->next->bFull))
{
ResetEvent(eProcessed);
break;
}
} while (k = k->next); // next element after each loop
}
}
return 1;
}
Details:
Now something makes me believe that the error is not in there, because the substring error is very rare. I have been only able to reproduce it with 100% chance when pressing Mouse_Down+Wnd+Tab to scroll through windows and keeping it pressed for some time (while it certainly happened on other cases as well). I avoid posting the whole code because it's a bit large and confusion is unavoidable. If the error is not here I will edit the post and add more code.
Thanks in advance
There does not appear to be any thread synchronization here. If one thread reads from the structure while the other writes, it might be read during initialization, with a non-empty list containing an empty string (or something invalid, in between).
If there isn't a mutex or semaphore outside the posted function, that is likely the problem.
All the size calculations appear to be valid for Windows, although I didn't attempt to run it… and <= … -1 instead of < in i <= (itr->size()-1) and 2 instead of sizeof (wchar_t) in new wchar_t[_size/2](); are a bit odd.
The problem with your code is that while thread 2 correctly waits for the data and thread 1 correctly notifies about them, thread 2 doesn't prevent thread 1 from doing anything with them under its hands while it still process the data. The typical device used to solve such problem is the monitor pattern.
It consist of one mutex (used to protect the data, held anytime you access them) and a condition variable (=Event in Windows terms), which will convey the information about new data to the consumer.
The producer would normally obtain the mutex, produce the data, release the mutex, then fire the event.
The consumer is more tricky - it has to obtain the mutex, check if new data hasn't become available, then wait for the Event using the SignalObjectAndWait function that temporarily releases the mutex, then process newly acquired data, then release the mutex.
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.