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.
Related
I have defined a base class using std::thread. For the child class, I perform some initialization of member variables and then start the thread using m_thread.reset(new std::thread(&MyClass::ThreadMain, this)); where m_thread is a member of MyClass. The purpose of the class is to read data from a serial port and report to a parent. The posix message queue handle of the parent is passed to MyClass during initialization before the thread is created. On running I get exceptions and I see that member variables that were initialized before the thread started appear to be no longer valid using the watch in GDB.
It appears as if the first message on the serial port is received and passed validation in order to get to the SendToParent call. At this call, it appears that I lose the stack. I tried running cppcheck to see if I have any memory leaks or buffer overflows and found nothing.
void MyClass::ThreadMain(void)
{
ssize_t bytesRead = 0;
UINT8 buffer[256];
UINT8 message[256];
BOOL partialMessage = FALSE;
UINT8 messageIndex = 0;
UINT8 payloadLength = 0;
// read data from the UART
while(1)
{
// the UART is setup to pend until data is available
bytesRead = read(m_radioFileDescriptor, buffer, sizeof(buffer));
if (FAIL == bytesRead)
{
LOG_SYSTEM_INFO("UART Read interrupted by a system call");
}
else if (bytesRead > 0)
{
// build the message
for(ssize_t i = 0 ; i < bytesRead ; i++)
{
if (FALSE == partialMessage)
{
// have we found the start of the message?
if(START_BYTE == buffer[i])
{
// start of new message
messageIndex = 0;
message[messageIndex] = buffer[i];
partialMessage = TRUE;
messageIndex++;
}
}
else
{
// keep building the message until the expected length is reached
if(LENGTH_POSITION == messageIndex)
{
// capture the expected message length
message[messageIndex] = buffer[i];
messageIndex++;
payloadLength = buffer[i];
}
else
{
message[messageIndex] = buffer[i];
messageIndex++;
// check for expected length and end byte
if((messageIndex == payloadLength) && (END_BYTE == buffer[i]))
{
// this should be a valid message but need to confirm by checking for a valid checksum
UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END];
UINT8 calculatedChecksum = RadioProtocol::Instance().GenerateRadioChecksum(message, (payloadLength - CHKSUM_POS_FROM_END));
if (messageChecksum == calculatedChecksum)
{
SendToParent(message, payloadLength);
}
else
{
LOG_SYSTEM_ERROR("Checksum FAILURE");
}
// reset for the next message
partialMessage = FALSE;
messageIndex = 0;
}
else if((messageIndex == payloadLength) && (END_BYTE != buffer[i]))
{
// malformed message - throw out and look for start of next message
LOG_SYSTEM_ERROR("Bytes read exceeded expected message length");
partialMessage = FALSE;
messageIndex = 0;
}
}
}
} // end for loop of bytes read on the port
}
else
{
LOG_SYSTEM_INFO("Read returned 0 bytes which is unexpected");
}
}
}
void MyClass::SendToParent(UINT8* pMsg, UINT8 size)
{
if ((pMsg != NULL) && (m_parentQueueHandle > 0))
{
// message is valid - pass up for processing
MsgQueueMessage msgToSend;
msgToSend.m_msgHeader = UART_MESSASGE;
bzero(msgToSend.m_msgData, sizeof(msgToSend.m_msgData));
for (UINT8 i = 0; i < size; i++)
{
msgToSend.m_msgData[i] = pMsg[i];
}
if (FAIL == msgsnd(m_parentQueueHandle, &msgToSend, sizeof(msgToSend), IPC_NOWAIT))
{
LOG_SYSTEM_ERROR("FAILED to send message on queue");
}
}
}
This acts like I am performing a buffer overflow but I just can't see it. When I set a breakpoint at the line UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END]; all data in the watch window appear valid. If I step over to the next line then the data, m_parentQueueHandle as an example, gets blown away.
This is my first time working with c++11 threads and particularly with c++. Any help or insights would be appreciated.
I think I found the issue. I added a bunch of printfs and found that the destructor for the class was being called. Much further upstreamI had the parent object being created as a local variable and it was going out of scope. This caused the child to go out of scope but the threads were still running. I certainly need to clean up the threads in the destructor.
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.
It is easy enough in D to create a Queue type using the std.container.dlist.
I would like to have multiple threads but have them communicate with a queue, not with message passing (https://tour.dlang.org/tour/en/multithreading/message-passing). As I understand it the messages are designed to always receive data at particular points in the code; the receiving thread will block until the expected data is received.
(EDIT: I was informed about receiveTimeout but having a no timeout and just a check is really more appropriate in this case (maybe a timeout of 0?). Also I am not sure what the message API will do if multiple messages are sent before any any are received. I will have to play with that.)
void main() {
spawn(&worker, thisTid);
// This line will block until the expected message is received.
receive (
(string message) {
writeln("Received the message: ", text);
},
)
}
What I am needing is to merely receive data if there is some. Something like this:
void main() {
Queue!string queue// custom `Queue` type based on DList
spawn(&worker, queue);
while (true) {
// Go through any messages (while consuming `queue`)
for (string message; queue) {
writeln("Received a message: ", text);
}
// Do other stuff
}
}
I have tried using shared variables (https://tour.dlang.org/tour/en/multithreading/synchronization-sharing) but DMD is complaining that "Aliases to mutable thread-local data not allowed." or some other errors, depending.
How would this be done in D? Or, is there a way to use messages to do this kind of communication?
This doesn't answer the specific question but ti does clear up what I think is a misunderstanding of the message passing api...
just call receiveTimeout instead of plain receive
http://dpldocs.info/experimental-docs/std.concurrency.receiveTimeout.html
I use this:
shared class Queue(T) {
private T[] queue;
synchronized void opOpAssign(string op)(T object) if(op == "~") {
queue ~= object;
}
synchronized size_t length(){
return queue.length;
}
synchronized T pop(){
assert(queue.length, "Please check queue length, is 0");
auto first = queue[0];
queue = queue[1..$];
return first;
}
synchronized shared(T[]) consume(){
auto copy = queue;
queue = [];
return copy;
}
}
I have gotten the answer I need.
Simply put, use core.thread rather than std.concurrency. std.concurrency manages messages for you and does not allow you to manage it yourself. core.thread is what std.concurrency uses internally.
The longer answer, here is how I fully implemented it.
I have created a Queue type that is based on an Singly Linked List but maintains a pointer of the last element. The Queue also uses standard component inputRange and outputRange (or at least I think it does) per Walter Brights vision (https://www.youtube.com/watch?v=cQkBOCo8UrE).
The Queue is also built to allow one thread to write and another to read with very little mutexing internally so it should be fast.
The Queue I shared here https://pastebin.com/ddyPpLrp
A simple implementation to have a second thread read input:
Queue!string inputQueue = new Queue!string;
ThreadInput threadInput = new ThreadInput(inputQueue);
threadInput.start;
while (true) {
foreach (string value; inputQueue) {
writeln(value);
}
}
ThreadInput being defined as thus:
class ThreadInput : Thread {
private Queue!string queue;
this(Queue!string queue) {
super(&run);
this.queue = queue;
}
private void run() {
while (true) {
queue.put(readln);
}
}
}
The code https://pastebin.com/w5jwRVrL
The Queue again https://pastebin.com/ddyPpLrp
I have a subclass of Gtk.Box that contains a GLib.Timer that fires a notification after a given interval. I have method in this class that calls this.destroy() on the Gtk.Box. The timer continues to run and fires the notification even after its parent instance has been destroyed. All instances of this class that have been destroyed exhibit this behaviour and continue to use CPU and memory untill the process is killed.
How do I fix this? How can I kill instances effectively and how do I manually free memory instead of relying on vala's garbage collection.
edit: here's an (embarrassing) mvce
// mvce_deletable
// nine
// 2017.01.11
// valac --pkg gtk+-3.0 --pkg glib-2.0 deletablebox.vala
using Gtk;
using GLib;
class RemovableBox : Gtk.Box {
private Gtk.Button delete_button;
private GLib.Timer timer;
private Gtk.Label label;
public RemovableBox () {
delete_button = new Gtk.Button.with_label ("DESTROY");
delete_button.clicked.connect (()=>{this.destroy();});
this.add (delete_button);
label = new Gtk.Label ("0000000");
this.add (label);
timer = new GLib.Timer ();
timer.start ();
Timeout.add (50, update);
this.show_all ();
}
private bool update () {
if (timer.elapsed () > 10.0f) {
stdout.printf("and yet it breathes\n");
}
label.set_text ("%f".printf(timer.elapsed()));
return true;
}
}
int main ( string [] args ) {
Gtk.init(ref args);
var window = new Gtk.Window ();
window.destroy.connect (Gtk.main_quit);
var delete_me = new RemovableBox ();
window.add ( delete_me );
window.show_all();
Gtk.main();
return 0;
}
I added a timer_id the the RemovableBox class but it still doesn't work as desired.
class RemovableBox : Gtk.Box {
private Gtk.Button delete_button;
private uint timeout_id;
private GLib.Timer timer;
private Gtk.Label label;
public RemovableBox () {
delete_button = new Gtk.Button.with_label ("DESTROY");
delete_button.clicked.connect (()=>{this.destroy();});
this.add (delete_button);
label = new Gtk.Label ("0000000");
this.add (label);
timer = new GLib.Timer ();
timer.start ();
timeout_id = Timeout.add (40, update);
this.show_all ();
}
~ RemovableBox () {
Source.remove (timeout_id);
}
private bool update () {
if (timer.elapsed () > 10.0f) {
stdout.printf("and yet it breathes\n");
}
label.set_text ("%f".printf(timer.elapsed()));
return true;
}
}
GLib.Timer is a stopwatch that returns the elapsed time. It doesn't generate events, but GLib.Timeout does.
GLib makes use of an event loop. This is the same for GTK+, which uses the same underlying GLib event loop. GLib.Timeout is used to create one kind of event source - a timer that fires after a given interval. When your program creates the event source you are given an identifier for the source. For example:
timer_id = Timeout.add_seconds (1, my_callback_function);
What your program needs to do is store that timer identifier in the object and then when the button click handler is called you can remove the timer as a source of events:
Source.remove (timer_id);
Strictly speaking Vala doesn't have a garbage collection cycle. Other languages will collect references that are no longer used and then remove the resources allocated to them during a clean up cycle. Vala uses reference counting, but it is deterministic. So when an object is no longer used, usually when it goes out of scope, the resources allocated to the object are removed immediately. For normal objects in Vala, rather than compact classes, a destructor is also called when the object is freed. This allows for the resource allocation is initialization (RAII) pattern to be used effectively in Vala.
In general you should not be manually freeing objects, Vala's reference counting is very good. I think it is important to understand GLib's event loop and sources of events to understand what is going on. For a detailed description see GLib's documentation on its main event loop.
Now you have provided a MCVE we can look in detail at how Vala manages memory. If you want to dig deep into what is going on behind the scenes you can use the --ccode switch with valac.
The first line of interest in your program is:
Timeout.add (50, update);
Looking at the C code from valac this line uses the g-timeout-add-full () function:
g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 50, _removable_box_update_gsource_func, g_object_ref (self), g_object_unref);
The crucial part here is g_object_ref (self). This increases the reference count for the object by one and passes a pointer to the object. This makes a lot of sense, because the update () callback passed in the Vala code makes use of the instance data from the object. Vala is doing the right thing and making sure that the instance data is kept alive while the timer is around. The 'g_object_unref' is called when the source is removed. Here's a modified version of your program putting this understanding in to practise:
// mvce_deletable
// nine
// 2017.01.11
// valac --pkg gtk+-3.0 deletablebox.vala
using Gtk;
class RemovableBox : Gtk.Box {
private Gtk.Button delete_button;
private uint timeout_id;
private GLib.Timer timer;
private Gtk.Label label;
public RemovableBox () {
delete_button = new Gtk.Button.with_label ("DESTROY");
delete_button.clicked.connect (()=>{this.tidy_up_and_destroy ();});
this.add (delete_button);
label = new Gtk.Label ("0000000");
this.add (label);
timer = new GLib.Timer ();
timer.start ();
timeout_id = Timeout.add (40, update);
this.show_all ();
}
~ RemovableBox () {
print ("RemovableBox destructor called\n");
}
private bool update () {
if (timer.elapsed () > 10.0f) {
stdout.printf("and yet it breathes\n");
}
label.set_text ("%f".printf(timer.elapsed()));
return true;
}
private void tidy_up_and_destroy () {
print ("RemovableBox.tidy_up_and_destroy called\n");
Source.remove (timeout_id);
this.destroy ();
}
}
void main ( string [] args ) {
Gtk.init(ref args);
var window = new Gtk.Window ();
window.window_position = WindowPosition.CENTER;
window.resize (250,50);
window.destroy.connect (Gtk.main_quit);
window.add (new RemovableBox ());
window.show_all();
Gtk.main();
}
Previously the program still kept a reference to the RemovableBox object and so was never completely removed. By removing the event source first then calling this.destroy (); it means there are no more references and the object is removed.
There is one other important point here. The lines:
var delete_me = new RemovableBox ();
window.add ( delete_me );
in main () have been changed to:
window.add (new RemovableBox ());
Vala objects exist for the scope of the block they were created in. By assigning the object to delete_me you are keeping a reference to the object for the rest of the main () block. By changing that to be an argument of a method call it is just for the call and so is freed when the button is clicked.
By the way, GLib is automatically included when using valac so there is no need for using GLib; or compiling with --pkg glib-2.0.
You are confusing automatic reference couting with full garbage collection.
There is no garbage collector in GLib, but classes have a reference count instead that is increased when a GObject is used in multiple places and decreased when it is no longer used in those places, until it reaches zero. The object is then freed.
In fact in C code the reference counting is manual:
// Reference count is set to 1 on gobject_new
gpointer obj = gobject_new (G_SOME_OBJECT, NULL);
// It can be manually increased when the object is stored in multiple places
// Let's increase the ref count to 2 here
gobject_ref (obj);
// Let's decrease it until it reaches 0
gobject_unref (obj);
gobject_unref (obj);
// Here the object is destroyed (but the pointer is still pointing to the previous memory location, e.g. it is a dangling pointer)
// gobject_clear (obj) can be used in situation where the variable is reused
// It still only unrefs the object by 1 though! In addition it will set obj to NULL
Vala adds the auto to reference counting, which makes it "automatic reference counting" (ARC). That is you don't have to worry about the reference count in Vala, it will add the appropriate ref and unref operations for you.
In full garbage collection (like in C#, Java, ...) memory deallocation is not deterministic, the object can be kept alive even if it isn't used anymore. This is done using something called a "managed heap" and a garbage collector is run in the background (i.e. as a GC thread).
Now that we have the background stuff covered to your actual problem:
You have to remove the Gtk.Box from it's parent container and also set any references you might still have in your Vala code to null in order to get the reference count to 0. It will then be unrefed.
There are of course other options, like disabling the timer, etc. You should really add an MVCE to your question for us to be able to give you some design advice on your code.
PS: Reference counting is often considered as a simple method of garbage collection. That's why I write full garbage collection (also called tracing garbage collection) in order to not confuse the two terms. See the Wikipedia article on garbage collection.
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.