-1

Help me understand this. Here is the context.

  • I am writing a program in C++.
  • I have 2 buffers (deque). Let's call them buffer1 and buffer2;
  • I have 2 threads: one thread is filling buffer1 with random values. The other one is copying the oldest buffer1 value to buffer2;
  • I am using mutexes.

I want to copy the value inside the 1st position of buffer1 to the buffer2 and, in order to perform to do this, I write the following code line:

THREAD 1

   double a = 20.1;
   buffer1.push_back(a);

THREAD 2

buffer2.push_back(buffer1.front());

My question is: performing this, am I copying the value or passing the value by reference? I explain my question. I am having a random memory problem while running the program. I want to be sure if the source of the problem is here.

Thank you, everyone.

Filipe Santos
  • 61
  • 2
  • 9
  • 1
    What's inside your containers? Ideally, you'd provide a [MCVE]. – 5gon12eder Jan 20 '16 at 15:57
  • 3
    Was the documentation for [`front`](http://en.cppreference.com/w/cpp/container/deque/front) and[`push_back`](http://en.cppreference.com/w/cpp/container/deque/push_back) not clear on what happens? – NathanOliver Jan 20 '16 at 15:57
  • @StoryTeller, you were right. It was a mistake commited here, but not in the program. Thank you! I edited the post. – Filipe Santos Jan 20 '16 at 16:09
  • @5gon12eder, the container has doubles. – Filipe Santos Jan 20 '16 at 16:09
  • @NathanOliver, perhaps I am having a problem to interpret the documentation (translation issues) :p it is not very clear, to me. I don't understand if i am copying (push_back) the reference given by front() or if I am copying the value given by the reference of front(). – Filipe Santos Jan 20 '16 at 16:09
  • @AndyG, sorry for the lack of information in the original post. I am using mutexes already :/ – Filipe Santos Jan 20 '16 at 16:10
  • If the deque contains native types like `double`, then the problem is not with the `deque` (or the underlying `vector`) but in how you use them. And if you have multiple thread then you *really* need to protect the containers (or container adapters) if you multiple threads can access them simultaneously. Read more about the [standard thread support library](http://en.cppreference.com/w/cpp/thread), especially about its [mutual exclusion](http://en.cppreference.com/w/cpp/thread#Mutual_exclusion) facilities. – Some programmer dude Jan 20 '16 at 16:10
  • You cannot "push back a reference" because the deque (or its underlying container) does not contain references. You pass a reference to `push_back` but there its lifetime ends. – n. m. could be an AI Jan 20 '16 at 16:20

3 Answers3

2

To start lets take a look at the functions you're calling. The std::deque::push_back function takes its argument by reference, so no copying there. And std::deque::front returns a reference (or const_reference) so no copying there either.

Now lets take a look at the underlying container, which defaults to std::vector, and it's the same story with its push_back and front functions as for std::deque.

However if you look closer at the std::vector::push_back reference, you will see that for the first overload the data needs to be CopyInsertable, because that's really how the element inside the vector is initialized, by copying the object you "push back" (or moving if your compiler and the data type supports it).

So in the end, if you have a complex class you should follow the rules of three, five or zero, and if it does that then you should be alright and not have memory problem regarding this anyway. If you do follow the rules of three, five or zero, and still have problems, then the problem might be somewhere else. Try to use a memory debugger like e.g. Valgrind or similar. And if you have a multi-threaded application you need to protect resources that can be modified by multiple threads simultaneously (using e.g. mutexes or semaphores).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

According to this std::deque::front returns a reference to the first element:

deque::front:

Returns a reference to the first element in the deque container.

And according to this deque::push_back copies (or moves) the content of the given element:

deque::push_back:

Adds a new element at the end of the deque container, after its current last element. The content of val is copied (or moved) to the new element.

Randir
  • 78
  • 6
0

I would say your problem is somewhere else. Since you have the snippets in different threads, their order may not be defined. You can either end up with this sequence:

double a = 20.1;
buffer1.push_back(a);
buffer2.push_back(buffer1.front());

in which case everything goes ok, or with this sequence:

buffer2.push_back(buffer1.front());
double a = 20.1;
buffer1.push_back(a);

in which case you call buffer1.front() on an empty container. Copy constructor gets called on some random data and yields memory problems.

Adam Trhon
  • 2,915
  • 1
  • 20
  • 51