原因
- 访问空指针
- 访问不可访问的内存
- 访问不可访问的变量 / 已经不在可访问作用域的变量,即便 gdb 调试可以展示变量值
案例
1 2 3 4 5 6
| 使用 seastar 时,调用返回 future 方法的方法,参数包含局部变量。在执行 then 回调时,局部变量已经不可访问(使用 gdb 调试仍可展示数值)。 解决方法是使用 seastar::do_with(std::move(v), [](V &v) { ... })
定义的方法返回值类型不为 void,但是没有 return 语句,定义 std::function 对象,在析构时报 segmentation fault
|
Lambda
shared_ptr
shared_ptr 引用导致的内存非法访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class A { public: int a; };
std::function<void()> fun() { std::shared_ptr<A> sa = std::make_shared<A>(); sa->a = 2; auto f = [&] { std::cout << "sa-> " << sa->a << std::endl; sa->a = 1; }; return f; }
void test() { std::cout << "----- in test -----" << std::endl; fun()(); std::cout << "----- out test -----" << std::endl; }
|
调用
1 2 3 4
| int main() { test(); return 0; }
|
输出
1 2 3 4
| ----- in test ----- sa-> 281314120
Process finished with exit code 138 (interrupted by signal 10: SIGBUS)
|
原因
lambda 表达式使用引用访问局部变量,在 fun()
返回 lambda 表达式对象时,局部变量 sa
已被释放,在 test
中执行 lambda 表达式时会访问已被释放的内存。
解决
使用拷贝替换引用,增加引用计数。
1 2 3 4 5 6 7 8 9
| std::function<void()> fun() { std::shared_ptr<A> sa = std::make_shared<A>(); sa->a = 2; auto f = [&, sa] { std::cout << "sa-> " << sa->a << std::endl; sa->a = 1; }; return f; }
|
输出
1 2 3 4 5
| ----- in test ----- sa-> 2 ----- out test -----
Process finished with exit code 0
|