HeapFree() Possible Causes of Crash - c++

typedef inside header file:
typedef struct tagMYSTRUCT {
wchar_t mystr[40] = { 0 };
DWORD threadId = NULL;
HANDLE threadHandle = NULL;
HWND receiverWnd = NULL;
} MYSTRUCT, *PMYSTRUCT;
Thread creation:
MYSTRUCT ats = *(PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
wcscpy(ats.mystr, L"hello");
ats.threadHandle = CreateThread(NULL, 0, MyThread, &ats, 0, &(ats.threadId));
This is thread which uses HeapFree() function. But it crashes. I believe this is bad practice but I want to know why. What is the logic behind and why HeapFree crashes program?
DWORD WINAPI MyThread(LPVOID lpParam) {
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
if (lpParam != NULL) {
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
...
}

You've obviously come from another language that blends the concepts of pointers and references differently than C++. Your usage is wildly inappropriate in C++. You have complicated things further by using non-standard functions (HeapAlloc() which is windows specific, not C++, etc) to manage memory.
If you are going to use HeapAlloc() (which is non-standard C++, being windows specific) or any standard function that dynamically allocates memory, the result needs to be stored in a pointer.
MYSTRUCT ats = *(PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
wcscpy(ats.mystr, L"hello");
ats.threadHandle = CreateThread(NULL, 0, MyThread, &ats, 0, &(ats.threadId));
What this does is convert the pointer returned by HeapAlloc() into a pointer to MYSTRUCT, dereferences that pointer which interprets that memory location as the value of a MYSTRUCT, and copies that value into ats.
At the least this is a memory leak - the memory allocated by HeapAlloc() is lost (never used again, it's address not stored anywhere), and you are passing the address of ats to the thread function.
There is therefore NO RELATIONSHIP between the memory allocated by HeapAlloc() and the address passed to the thread function.
Even worse is the thread function itself, which I've simplified here
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
if (lpParam != NULL)
{
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
}
lpParam is going to contain the address of ats from the function that was passed by the function creating the thread.
If the function creating the thread has returned (after all, threads run in parallel) then that ats will no longer exist. If that happens, lpParam will be a dangling pointer (the address of an object that no longer exists as far as your program is concerned).
ActiveStruct is now going to be a local object which contains a copy of the object at the address passed to the function. In other words, it is a local copy of ats allocated previously by the func. If that ats has ceased to exist, and the address passed is dangling, the simple act of creating ActiveStruct causes undefined behaviour.
Even worse, lpParam is the address of (what was) ats. If ats still exists (i.e. the function which created the thread hasn't returned), it was not created on the heap, so should not be released using HeapFree(). If it no longer exists, then it shouldn't be passed to HeapFree() either. Either way, HeapFree() is being asked to release memory that was not allocated using HeapAlloc(). That will be virtually guaranteed to cause a runtime error.
At minimum, you need to change the code which creates the thread to
MYSTRUCT *ats = (PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT)); // note changed position of *
wcscpy(ats->mystr, L"hello"); // note usage of ats as a pointer
DWORD threadID; // we need these since ats is being released by the thread function
HANDLE threadHandle; // it is not a good idea for CreateThread() to use them
threadHandle = CreateThread(NULL, 0, MyThread, ats, 0, &(threadId)); // changes since ats is now a pointer
and the thread function to
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT *ActiveStruct = (PMYSTRUCT)lpParam; // this is now a pointer
if (lpParam != NULL)
{
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
}
Since you are making fundamentally wrong assumptions about the C++ memory model, I would assume other things (which you haven't shown) are wrong in your code. But this should get you started.

You are getting in something of a mess over this. You are passing the address of a stack allocated structure which you do not intend to do. I think it's clear that you intend to pass the address a heap allocated structure. When you try to deallocate that structure, calling HeapFree, you encounter a runtime error because you passed to HeapFree the address of memory not allocated by HeapAlloc.
I'll show you how it is done using new and delete rather than HeapAlloc and HeapFree. There's really no need to use HeapAlloc here. Use the standard C++ memory allocator.
MYSTRUCT *pats = new MYSTRUCT(); // zero initialise
wcscpy(pats->mystr, L"hello");
DWORD threadId;
HANDLE threadHandle = CreateThread(NULL, 0, MyThread, pats, 0, &threadId);
....
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
delete (PMYSTRUCT)lpParam;
// if you want the thread ID, call GetCurrentThreadId
// or if you want a thread handle call GetCurrentThread
}
Note that I did not attempt to store the thread handle and thread ID directly into the structure. That's because the structure could in theory be destroyed before the call to CreateThread returns. I'm using local variables instead. If your thread needs to find its ID, or obtain a handle to itself, there are API calls to do that.

1) you are not checking pointers before casting and dereferencing them
2) you are actually allocating MYSTRUCT on the stack and copy zeros from a heap-allocated buffer of MYSTRUCT size
3) your heap-allocated pointer leaks after copy assignment
4) you are passing pointer to stack-allocated MYSTRUCT instance to CreateThread which becomes invalid right after MYSTRUCT goes out of scope (which may happen at any time before new thread starts, while it works, or after it exits)
5) CreateThread and c++ runtime don't play well together

this is the corrected version if you insist on using HeapAlloc
PMYSTRUCT ats = (PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
if(ats == NULL)
return; // exit, throw do something
wcscpy(ats->mystr, L"hello");
CreateThread(NULL, 0, MyThread, ats, 0, &(ats.threadId));
HeapAlloc returns a pointer to the allocated memory, that is placed in a pointer. The pointer is then used to manipulate the allocated struct, finally this pointer is passed to the thread. And dont assign the result of createthread to something this is destroyed by the thread.

Related

How to pass in the 'this' pointer to a C++ WinAPI thread?

I am trying to run a C++ thread but also pass in the instance to the class itself. I cannot seem to figure it out.
I have a struct for parameters to the thread:
struct CLASS_PARAMS {
SomeClass* ptr;
};
I then call my setup method:
void SomeClass::setup() {
CLASS_PARAMS params;
params.ptr = this;
CreateThread(NULL, 0, SetupThread, &params, 0, NULL);
}
and right above SomeClass::setup(), I define SetupThread:
DWORD WINAPI SetupThread(LPVOID lpParam) {
CLASS_PARAMS* params = (CLASS_PARAMS *) lpParam;
SomeClass* inst = params->ptr;
....
....
}
However, I get read-access violations on using inst. I have other methods in SomeClass that I need to access via the thread:
inst->getSomeValue();
...
inst->setSomeValue(someValue);
...
but it will not allow me. Any suggestions on what I'm doing wrong?
You allocate CLASS_PARAMS on stack, so it is destroyed before used.
Allocate it dynamically, pass pointer and free it in the thread.
Alternatively, if you need to pass only this, pass it without wrapping structure, just cast to LPVOID and back (but be sure to use the same class pointer type to avoid pointer adjustment bugs)

Pointer Value is changed when passed through Threadcreate

I am creating a new thread in which I am passing passing an object of class
class demo is defined in .h file
int threadentry(void* data)
{
demo* inst=(demo*) data;
cout << "Value of inst "<<hex << &inst<< endl;//value is different from below
}
int main()
{
while(1)
{
demo* inst=new demo();
cout << "Value of inst "<<hex << &inst<< endl; //value is coming different from above
HANDLE threads;
DWORD threadId1;
if ((threads = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadentry,
(void *)inst, 0, &threadId1)) == NULL)
return -1;
delete inst;
system("pause");
}
}
I think value should be different because address is copied in data variable of threadentry. How can I check that these are the same object passed.
The code is printing the address of a pointer, not the address of the object. There are two pointer variables involved (one is declared in main() and the other is the argument of the thread function) so the output is different. Drop the &, address of operator, from the output statements:
cout << "Value of inst "<<hex << inst << endl;
Give ownership of the supplied object to the thread as it knows when it has finished using it. In the posted code the object is deleted after the thread is created, possibly resulting in the thread using a dangling pointer. Move the delete of object from main into the thread.
The signature of the thread function is:
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
and it must return a value, the posted code does not.
The code also has a resource leak as the handle returned from CreateThread() is not being closed. Either CloseHandle() immediately if the thread does not need to be joined with or store the thread handles, in a std::vector for example, to be joined with (using WaitForSingleObject for example) and closed later.
You might get a race condition. You delete your class instance right after CreateThread. At this point threadentry() might not start executing yet.

Variables overlap when calling thread twice in C++

I'm having a problem calling a thread more than once and the variables messing up. I'm new to threads, so I'm sure I'm missing something simple.
struct PARAMS
{
time_t secondsAtStart;
};
DWORD WINAPI ProcessChange(void* parameter) {
PARAMS* params = (PARAMS*)parameter;
Sleep(3000);
_tprintf(TEXT("Seconds: (%d)\n"), params->secondsAtStart);
return 0;
}
void FileChanged(CString filename, CString action) {
struct PARAMS *params = NULL;
params = (struct PARAMS *)malloc(sizeof(PARAMS)+1);
params->secondsAtStart = time(null);
// I've also tried it this way.
//PARAMS params;
//params.secondsAtStart = time(NULL);
HANDLE hThread = CreateThread(NULL, 0, ProcessChange, &params, 0, NULL);
// If I uncomment this, it works, but just one thread runs at a time.
//WaitForSingleObject(hThread, INFINITE);
}
If I don't uncomment the WaitForSingleObject, then the secondsAtStart variable gets corrupted. The end result I need is that if FileChanged gets called 3 times right after one another, I'm going to have the first two runs do nothing and the last one do the action.
Thanks,
Ben
Passing addresses of (or references to) local variables of a function, i.e. variables of automatic storage, to a thread causes undefined behaviour if the thread lives longer than the function.
In your code, params points to an object of dynamic storage, but the pointer itself is a local variable. You pass its address &params to the thread. This only works if by waiting for the thread to finish you guarantee the pointer lives longer than the thread. Otherwise it causes undefined behaviour, which quite naturally manifests itself in nonsensical values being printed.
Passing params instead of &params should solve the problem. (Also note that the code as written causes a memory leak; you'll need to make sure you actually free the space allocated after the thread has finished.)

Thread is showing inconsistence result

I am creating 5 thread here using ThrdFunc. Here each thread update the listBox.
I was expecting message in this way. Initially come in this way but after some time
Thread1:Adding msg
Thread2:Adding msg
Thread3:Adding msg
But after some time I get message like
Thread0:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg
This is the code:
for (int i = 0;i<6;i++)
{
nThreadNo = i+1;
hWndProducer[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProducerThrdFunc,(void*)&nThreadNo,0,&dwProducerThreadID[i]);
if (hWndProducer[i] == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
}
DWORD WINAPI ThrdFunc ( LPVOID n )
{
int *nThreadNo = (int*)n;
char chThreadNo[3];
memset(chThreadNo,0,3);
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," Thread No:");
strcat(pMsg1,chThreadNo);
strcat(pMsg1," Adding Msg:");
PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0);
}
return 0;
}
Most likely nThreadNo is allocated on the stack. You're giving each thread a pointer to one of it's elements.
Once the function creating the threads returns, the array is no longer valid, but the thread functions are still pointing to it. The memory the threads are holding pointers to will most likely be overwritten, causing what was originally the thread ID to be overwritten with garbage.
Anything you pass another thread should generally be allocated on heap, either via malloc type functions or new, preferably new since this is C++.
For example, instead of int nThreadNo[6], use int* nThreadNo = new int[6]. However, keep in mind that you will have to delete[] the memory nThreadNo points to when you're done with it.
Well, I can't be sure because you've not given all your code.
However, it looks like nThreadNo is a local variable, defined on the stack of the main thread. You are passing the address of this variable to the threads, but you should be passing the value, or passing some heap allocated memory.
What you are doing is morally equivalent to returning from a function a pointer to a local variable, e.g.
int* foo()
{
int i;
return &i;
}
The simplest way to make your code behave is to make the following changes:
CreateThread(..., (void*)nThreadNo, ...
int nThreadNo = (int)n;
nThreadNo has to be global because you are giving a pointer to it to your new thread.

how to write pthread_create on the same function?

Could someone please help with this? I have the following:
// part_1
if (pthread_create(&threadID, NULL, ThreadMain,
(void *) clientSocket) != 0) {
cerr << "Unable to create thread" << endl;
exit(1);
}
// part_2
void *ThreadMain(void *clientSocket) {
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
I would to have part_2 in part_1 ( I mean without calling TreadMain() function )
thanks for your replies
What if you could do this?
pthread_create() has to create a new stack for the new thread to use. If pthread_create() copied the existing thread's old stack into a separate block of memory to create a new stack, then what would happen to local variables that point to other local variables? The local variables on the new stack would point to the old stack. When the thread using the old stack (the one that called pthread_create()) returns or overwrites them, those variables start pointing to invalid data.
But what about fork()? Why doesn't fork() take a function pointer like pthread_create()? Well, unlike pthread_create(), the new thread of execution created by fork() doesn't have to live in the same address space as the old thread of execution, because they are in separate processes. fork() clones the parent process's virtual address space, stack, heap, and all. The child process's stack variables have the same virtual addresses as the corresponding variables in the parent process. So all of the pointers in the new child process continue to be valid*, no matter what the old parent process does with the memory.
* Nitpicker's corner: excluding pointers that were invalid to begin with, as well as memory that is deliberately shared
If all you want to do is simply move the function for part2 inside part1, you can create a local class inside of part1, with a static member function...
class LocalFunctor
{
public:
static void *ThreadFunc(void* clientSocket)
{
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
};
then call LocalFunctor::ThreadFunc within pthread_create
pthread_create(&threadID, NULL, LocalFunctor::ThreadFunc,(void *) clientSocket)
If you're going to do this more than once, look at boost::thread or wrap this up inside a template helper class.
You could get an Apple Macintosh computer with OS 10.6 and start programming with Grand Central Dispatch. Apple added some new C compiler features that do almost exactly what you seem to want. They're called Blocks.