Skip to content

Instantly share code, notes, and snippets.

@rmartinho
Last active December 15, 2015 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmartinho/5221269 to your computer and use it in GitHub Desktop.
Save rmartinho/5221269 to your computer and use it in GitHub Desktop.
Never pass vectors by reference. Wait, never pass ints by reference. Better, never pass anything by reference.
struct Gadget
{
std::vector<Widget> w;
};
void thread1()
{
Gadget g;
launch_async(unsafe(g.w));
}
void unsafe(const std::vector<Widget> &p)
{
longComputation();
//in the meantime, thread1 finished and its local `g` was destroyed
p.clear(); //dangling
}
//Should have been:
void safe(std::vector<Widget> p)
{
longComputation();
p.clear(); //`g` is dead, but object pointed to by `g.w` still persits due to `p` referencing it
}
struct Gadget
{
int w;
};
void thread1()
{
Gadget g;
launch_async(unsafe(g.w));
}
void unsafe(const int &p)
{
longComputation();
//in the meantime, thread1 finished and its local `g` was destroyed
p += 1; //dangling
}
//Should have been:
void safe(int p)
{
longComputation();
p += 1; //`g` is dead, but object pointed to by `g.w` still persits due to `p` referencing it
}
template <typename T>
struct Gadget
{
T w;
};
template <typename T>
void thread1()
{
Gadget<T> g;
launch_async(unsafe(g.w));
}
template <typename T>
void unsafe(const T &p)
{
longComputation();
//in the meantime, thread1 finished and its local `g` was destroyed
p.doStuff(); //dangling
}
//Should have been:
template <typename T>
void safe(T p)
{
longComputation();
p.doStuff(); //`g` is dead, but object pointed to by `g.w` still persits due to `p` referencing it
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment