RPC client dangling reference fix (#34)
* Fix dangling reference * Add docs for the dangling reference in lambda captures Co-authored-by: Antonio Andelic <antonio.andelic@memgraph.io>
This commit is contained in:
parent
9b984ab2f2
commit
f273be63a2
@ -29,6 +29,33 @@ You should use a pointer to `const` then. The primary reason being is that
|
||||
references obscure the semantics of moving an object, thus making bugs with
|
||||
references pointing to invalid memory harder to track down.
|
||||
|
||||
Example of this can be seen while capturing member variables by reference
|
||||
inside a lambda.
|
||||
Let's define a class that has two members, where one of those members is a
|
||||
lambda that captures the other member by reference.
|
||||
|
||||
```cpp
|
||||
struct S {
|
||||
std::function<void()> foo;
|
||||
int bar;
|
||||
|
||||
S() : foo([&]() { std::cout << bar; })
|
||||
{}
|
||||
};
|
||||
```
|
||||
What would happend if we move an instance of this object? Our lambda
|
||||
reference capture will point to the same location as before, i.e. it
|
||||
will point to the **old** memory location of `bar`. This means we have
|
||||
a dangling reference in our code!
|
||||
There are multiple ways to avoid this. The simple solutions would be
|
||||
capturing by value or disabling move constructors/assignments.
|
||||
Still, if we capture by reference an object that is not a member
|
||||
of the struct containing the lambda, we can still have a dangling
|
||||
reference if we move that object somewhere in our code and there is
|
||||
nothing we can do to prevent that.
|
||||
So, be careful with lambda catptures, and remember that references are
|
||||
still a pointer under the hood!
|
||||
|
||||
[Style guide reference](https://google.github.io/styleguide/cppguide.html#Reference_Arguments)
|
||||
|
||||
#### Constructors & RAII
|
||||
|
@ -34,10 +34,11 @@ class Client {
|
||||
res_load)
|
||||
: self_(self),
|
||||
guard_(std::move(guard)),
|
||||
req_builder_([&](const uint8_t *data, size_t size, bool have_more) {
|
||||
if (!self_->client_->Write(data, size, have_more))
|
||||
throw RpcFailedException(self_->endpoint_);
|
||||
}),
|
||||
req_builder_(
|
||||
[self](const uint8_t *data, size_t size, bool have_more) {
|
||||
if (!self->client_->Write(data, size, have_more))
|
||||
throw RpcFailedException(self->endpoint_);
|
||||
}),
|
||||
res_load_(res_load) {}
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user