Access violation, when using shared_ptr on legacy code - visual-c++

I implement a new module using shared_ptr etc. in our legacy app, however I get a access violation, when shared_ptr is calling the destructor.
app:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg)); // _stringmsg is initialized before
Process(msg);
break;
}
Process():
bool Process(std::tr1::shared_ptr<CDataMsg> msg)
{
try
{
switch (msg->getDataType())
{
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild> data(std::tr1::static_pointer_cast<CMyDataChild>(base));
// do some stuff with data
std::tr1::shared_ptr<CRequest> request(new CRequest(data->getParam1(), data->getParam2()));
handler->AddRequest(request->getBin());
break;
}
default:;
}
return true;
}
catch (...)
{
// exception handling
}
return false;
}
Destructor:
CDataMsg::~CDataMsg()
{
if (m_data)
delete m_data;
m_data = NULL;
}
m_data is a CMyData* (cannot be changed at this point).
CDataMsg is a container, which holds data of type CMyData. CmyDataChild is a subclass of CMyData, which is used here.
I have breakpoint in the destructor, but the debugger stops only, when shared_ptr is calling it and then I get the access violation already.

As you have confirmed in your comment msg->getData() returns a pointer to a member variable of msg (presumably m_data) and it will be deleted when this switch block scope exits:
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild>
data(std::tr1::static_pointer_cast<CMyDataChild>(base));
// do some stuff with data
std::tr1::shared_ptr<CRequest>
request(new CRequest(data->getParam1(), data->getParam2()));
handler->AddRequest(request->getBin());
break;
}
The destructor of msg will be invoked later when this switch block scope exits:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg));
Process(msg);
break;
}
and attempt to redelete the member variable m_data.
Also:
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild>
data(std::tr1::static_pointer_cast<CMyDataChild>(base));
...
}
data is pointing to the same object as base. When this scope exits base will be deleteded twice.

Whenever I see bugs like this, I immediately think double delete.
std::tr1::shared_ptr<CMyData> base(msg->getData());
if (m_data) delete m_data; //- in CDataMsg destructor
Is it possible that 'm_data' is being deleted twice? Once in the shared_ptr and once in the CDataMsg destructor.

Related

Return result of Invoking a Delegate from another thread

I've got a GUI with a TabControl. Each new TabPage is created via a new Thread. I want to call this->tabControl->TabCount, but the tabControl is owned by a thread other than the one I'm calling from. Therefore, I need to Invoke a delegate. However, all the examples I find online show printing to std::cout from each of the delegate methods. I need a return value, in this case an int.
delegate int MyDel();
int InvokeTabCount()
{
if (this->InvokeRequired)
{
MyDel^ del = gcnew MyDel(this, &MyTabControl::InvokeTabCount);
auto temp = this->Invoke(del); // can't just "return this->Invoke(del)"
return temp; // Invoke() returns a System::Object^
}
else
{
return this->tabControl->TabCount;
}
}
void CreateNewTab()
{
// do stuff
this->tabControl->TabPages->Insert(InvokeTabCount() - 1, myNewTab); // insert a tab
this->tabControl->SelectTab(InvokeTabCount() - 2); // OutOfBounds and tabPageNew
}
System::Void MethodToAddNewTabPage() //actually a click event but whatever
{
System::Threading::Thread^ newThread =
gcnew System::Threading::Thread(
gcnew System::Threading::ThreadStart(this, &MyTabControl::CreateNewTab));
newThread->Start();
}
Currently, my InvokeTabCount() method is returning -1 when I simply this->Invoke(del) without returning it. And I am unable to return it because my method expects to return an int instead of a System::Object^ which is what Invoke() returns. However, when debugging I find that auto temp contains the value 2 which is correct. And temp->ToString() contains the value "2" which would also be correct.
How do I return this->Invoke(del)?
Do I need to set the value of a global variable from within my InvokeTabCount() method? I suppose I could find a way to translate from System::String^ to std::string to utilize std::stoi(), but that seems like an odd workaround.
Current solution:
delegate int MyDel();
int InvokeTabCount()
{
if (this->InvokeRequired)
{
MyDel^ del = gcnew MyDel(this, &MyTabControl::InvokeTabCount);
auto temp = this->Invoke(del);
return int::Parse(temp->ToString());
}
else
{
return this->tabControl->TabCount;
}
}
The result is an integer, boxed and contained in an Object^ reference. You should be able to simply cast it to int.
If you want to be extra safe, do a null check and verify that temp->GetType() returns int::typeid, but that's probably overkill since you're creating the delegate (still in the typed form) right there.

__finally in C++ Builder 2010 losing scope?

Here is a very strange thing which I don't think should happen:
UnicodeString test = "abc";
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
// At this point the "test" variable should still be in scope???
test = "xyz"; // PROBLEM here - test is NULL instead of "abc"! Why?
}
If I remove the return a; in the try-catch block the test variable is still defined. Is there a particular reason why after the above construct the UnicodeString seems to go out of scope? Is it a bug with C++ Builder 2010? I understand that return returns from function but it should still retain variable scope in the __finally block shouldn't it?
I did a bit more analysis and it seams that once you execute return statement all local objects from stack are acting as destroyed. If you try using heap objects instead this won't happen.
UnicodeString *test = new UnicodeString("abc");
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
ShowMessage(*test); // "abc"
*test = "xyz";
}
delete test;
Using smart pointers like unique_ptr will again result in loosing an object in __finally since return will initiate it's destruction.
(Remy posted this in comments but did not post an answer here)
When a return statement is hit within a try...finally block, what happens is that any local objects are destroyed (as they would be for any other return) before the __finally block is entered.
So by the time your code gets up to test = "xyz";, test has already been destroyed, causing undefined behaviour.
I guess it is a matter of semantics whether you call this a bug or a design flaw, but either way it is something to bear in mind when using try...finally. My personal advice would be to just not use it at all; the Standard C++ techniques of try...catch and RAII can solve any problem.

Created pointer but how to write in class?

I have initialized Queue *q1, *q2; but it could not create the Queue in my Queue class
Main
Queue *q1, *q2; // Global variable
Queue class
// codes......
Queue::Queue() { // default constructor
size = 0;
front = 0;
rear = Q_MAX_SIZE -1;
}
Queue::~Queue() {
while(!isEmpty()) {
dequeue();
}
}
void Queue::enqueue(Car c) {
if (!isFull()) {
rear = (rear + 1) % Q_MAX_SIZE; // circular array
carQueue[rear] = c;
size++;
} else {
cout << "Queue is currently full.\n";
}
}
// codes.....
I cannot seem to initialize the Queue with the default constructor cause in debugging mode, it cannot read any size, front and rear.
The statement:
Queue *q1, q2;
Create one pointer variable (Queue*), and a normal variable of type Queue. Only for q2, which is of normal type Queue, the constructor will be called. You don't see constructor being called (in debugging mode), only because it is called BEFORE main, (or WinMain) - since it is global variable. Global variables are initialized before main routine.
You need to put a breakpoint with the constructor itself - Queue::Queue().
Hope this helps.

function return values c#

I am trying to get to grips with C# having not coded for many years and my previous experience being in ANSI C.
I have read a number of books and searched online but one aspect is evading me and I am hoping someone here can help.
In the past I would declare a function and if there was a possibility of something not happening within the function (i.e. file not found etc.) declare the return to be an integer. I would then return 0 if all was well and a value if not. The value would correspond to where the function failed to execute fully and I could branch accordingly from where I called it.
if(function1())
{
// all my error stuff, maybe a switch/case etc.
}
All the examples I have found in C# seem to avoid this technique and I was hoping to get some understanding here.
Thanks in anticipation.
(I know I am a fossil). :)
Exceptions are the approach you use in C# and similar languages.
It goes like this:
try
{
function();
}
catch(FileNotFoundException e)
{
// File not found
}
catch(UnauthorizedAccessException e)
{
// User doesn't have right to access file
}
// etc...
To make this work, function shouldn't return a status code but instead throw an exception in case of an error.
Please note that the exceptions I illustrated in the code block above are thrown by the framework if you try to access a file and one of those errors is happening. So you don't actually have to do this yourself.
Furthermore, in C# there is no implicit conversion from integral values to bool, i.e. if(function()) is invalid, if function returns an int. You would need to write it like this:
if(function() != 0)
{
// all your error stuff
}
There's nothing to stop you doing this (though there are better ways of handling the errors - exceptions for example).
If you do want to carry on with this approach, the biggest problem you are having is that in C# you can't treat an integer as a boolean so your if test won't compile. What you need is:
if (function1() != 0)
{
}
But to check the value you'd need:
int result = function1();
switch (result)
{
case 1:
// Handle this case
break;
case 2:
// Handle this case
break;
default:
// All OK
break;
}
It would be better to return an enumerated type for each error case so that you don't have magic numbers, but exceptions are the way to go:
try
{
function1();
}
catch (SpecificException1 e1)
{
// Handle this case
}
catch (SpecificException2 e2)
{
// Handle this case
}
What you shouldn't have is a general exception handler:
catch (Exception e)
{
}
This just hides other potential problems.
If you want to follow that pattern of checking return value instead of managing errors, you better use enumarations than plain numbers.
For example:
public enum ResultType
{
Error = 0,
Success,
Waiting
}
public ResultType function()
{
if (still_waiting)
return ResultType.Waiting;
if (error_has_occured)
return ResultType.Error;
return ResultType.Success;
}
public void Main()
{
ResultType result = function();
switch (result)
{
case ResultType.Success:
MessageBox.Show("all is good");
break;
case ResultType.Waiting:
MessageBox.Show("still waiting...");
break;
case ResultType.Error:
MessageBox.Show("error has occurred");
break;
}
}
Behind the scenes, it's still using numbers but you put some meaning to each number.
if(function()==1)
{
}
int function()
{
int returnVal =0;
// do stuff
// if true return returnVal =1 else set returnVal =0;
return returnVal;
}

How to apllcation can catch the event set by driver in wince 6.0?

I have wince 6.0 applcaion in which inside thread applcation is waiting for event which driver will set. i have created event inside applcation and samevent in driver also. butwhen driver set the event then appcation is not able to catch it.(driver is setting event successfully)
Here is code
// application side
m_hEvent = CreateEvent(NULL,FALSE,FALSE,L"MY_EVENT");
if(m_hEvent)
{
if(!DeviceIoControl(m_hDriver,CREATE_MY_EVENT,
(LPDWORD)&m_hEvent,NULL,NULL,NULL,NULL,NULL))
{
AfxMessageBox(L"not created event successfully in driver");
}
while(TRUE)
{
//waiting for driver to setevent
int RetValue = WaitForSingleObject(m_hEvent,INFINITE);
if(0 == RetValue )
{
AfxMessageBox(L"wait end");
}
else
{
AfxMessageBox(L"time out");
}
}
}
...
//Driver side
BOOL SMP_IOControl(DWORD hOpenContext, DWORD dwCode,
LPDWORD pBufIn, DWORD dwLenIn, LPDWORD pBufOut,
DWORD dwLenOut, PDWORD pdwActualOut)
{
switch (dwCode)
{
case CREATE_MY_EVENT :
{
m_hEvent = (HANDLE)(*pBufIn);
if(NULL != m_hEvent)
{
// getting this message
MessageBox(NULL,L"event successfully created",L"success",MB_OK);
}
else
{
MessageBox(NULL,L"no event successfully created",L"success",MB_OK);
}
}
break;
case SET_EVENT:
{
//set event that which application waiting
if(SetEvent(m_hEvent))
{
// getting this message
MessageBox(NULL,L"event set successfully",L"success",MB_OK);
}
else
{
MessageBox(NULL,L"event set successfully",L"success",MB_OK);
}
}
break;
}
}
The inherent problem here is that you're having one process (your app) create a HANDLE and then passing that HANDLE to the another process (device.exe) and expecting it to be valid. It's not.
In this case the solution is simple. System events are unique across the OS by name, so simply call CreateEvent in both places using the same text name. When you call SetEvent in one process, the other process waiting on the HANDLE it created will get signalled.
That means remove your CREATE_MY_EVENT IOCTL (and that's a non-standard naming convention, BTW, it should start with "IOCTL_") handling in the driver and just call CreateEvent in the SMP_Init method and store that HANDLE.

Resources