0

I have a udp client which has 2 threads.
The data which is received from socket is put into a queue which is processed by the second thread.

What is the proper way to do this?
Is this correct?

Case 1

char* buffer = new char[1024];
Receive the socket data in buffer
Lock mutex
_queue.push_back(buffer)
signal the waiting thread
Unlock mutex

//In second thread
while(1)
    while(queue not empty)
        Lock mutex
        const char* buf = _queue.front()
        _queue.pop();
        Unlock mutex
        ...
        Some strtok actions on buf **(This is causing crash)**
        ...
        delete[] buf    //Removing this line removes crash
    conditional wait
cppcoder
  • 22,227
  • 6
  • 56
  • 81
  • Just remove the instruction to delete the pointer and it should be fine. The pop returns the value and removes it from the queue :) The reason for the crash is most likely because you are trying to delete something which doesn't exist anymore. – GMasucci Nov 15 '13 at 16:29
  • @GMasucci Yes, I removed it and crash is gone. But valgrind is report memory leak for the same. Who will free the buffer? – cppcoder Nov 15 '13 at 16:30
  • 1
    nearly:) a sscce is a small version of your code which employs the same instructions and exactly replicates your error/issue – GMasucci Nov 15 '13 at 16:39
  • I have provided the relevant parts where I am dealing with the buffer. – cppcoder Nov 15 '13 at 16:42
  • 1
    if this is C++ and the inter-thread op is internal to your program (does not require C interface), might I suggest using a queue of managed memory, such as vector or string? – im so confused Nov 15 '13 at 16:43
  • to me it looks like your external interface ends at receiving the socket data. You can then wrap that in a managed object and send that along to the other thread for a more robust system – im so confused Nov 15 '13 at 16:44
  • Can you show me an example? You mean I have to use `vector` which has 1024 characters and put this vector inside the queue? – cppcoder Nov 15 '13 at 16:44
  • vector buffer(1024, 0); // zero-construct buffer – im so confused Nov 15 '13 at 16:47
  • queue> _queue; – im so confused Nov 15 '13 at 16:47
  • yes, exactly. Then your news/deletes are all gone – im so confused Nov 15 '13 at 16:47
  • Keep in mind that in this multithreaded environment, I am not sure about your thread-local storage or how you pass this queue, but this should work given what I can tell from the small amount of code – im so confused Nov 15 '13 at 16:48
  • queue is a global variable shared by both the threads. – cppcoder Nov 15 '13 at 16:49
  • you can use &buffer[0] or buffer.data() to access the pointer to the buffer itself for receiving the data from the socket – im so confused Nov 15 '13 at 16:49
  • Two things - thread-safe access to the std::queue, and how does the consumer thread know that there is something in the queue to pop? – Martin James Nov 15 '13 at 17:20
  • @MartinJames Added more code/algorithm used – cppcoder Nov 16 '13 at 04:57
  • once you convert your char * to std::string, use http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c/55680 to dump your use of strtok (which I find ugly due to its manipulation of the input string) – im so confused Nov 16 '13 at 20:27

2 Answers2

1

Standard C++ containers are not thread safe. You need to put some kind of blocking around the accesses to the queue, otherwise it's quite possible that front() is returning an invalid pointer.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 1
    That, and I don't see any signal that the consumer thread waits on to ensure that there is something in the queue to pop? – Martin James Nov 15 '13 at 17:22
  • @MartinJames I was assuming there is some code to do that but it wasn't shared with us. Good point though. – Mark Ransom Nov 15 '13 at 17:26
  • @MarkRansom `front()` & `pop()` is called inside a `while` which checks that queue is not empty and it is also mutex protected to avoid simultaneous `push` and `pop` – cppcoder Nov 16 '13 at 04:51
  • @cppcoder did it not occur to you that this was important information to put into the question? – Mark Ransom Nov 16 '13 at 16:02
0

1st issue: the crash If you remove the deletion instruction the crash should vanish as pop returns the value and deletes the pointer from the end of the queue for you.

2nd issue: memory leak

You are not actually deleting data, just pointers so you are effectively orphaning data when you delete the pointers, leading to your memory leak.

If you can post some code I may be able to help more:)

GMasucci
  • 2,834
  • 22
  • 42
  • @cppcoder an SSCCE is a little different from relevant code - by providing one, we can reproduce your error on our end and debug it more rapidly than on a forum waiting for your responses – im so confused Nov 15 '13 at 16:45
  • But `pop` doesn't call `delete` on the pointer, it simply removes it from the underlying container. – Mark Ransom Nov 15 '13 at 17:06
  • Sorry yes, was answering hurriedly, what I mean is it is not removing data from memory, just deleting the pointer from the queue – GMasucci Nov 16 '13 at 12:39