如何修复Valgrind检测到的“条件跳转依赖未初始化值”错误?
修复C++移动构造函数的Valgrind未初始化值错误
示例代码
#include <iostream> using namespace std; class A{ int * p; public: A(){ cout << "Default Constructor" << endl; p = new int[10]{0}; } A(const A& obj){ cout << "Copy Constructor" << endl; p = new int[10]{0}; for(int i=0;i<10;i++) p[i] = obj.p[i]; } A(A&& obj){ cout << "Move Constructor" << endl; delete [] p; p = obj.p; obj.p = nullptr; } A& operator = (const A & obj){ cout << "Copy Assignment Operator " <<endl; if(this == &obj) return *this; p = new int[10]{0}; for(int i = 0 ;i < 10;i++) p[i] = obj.p[i]; return *this; } A& operator = (A&& obj){ cout << "Move Assignment Operator" <<endl; if(this == &obj) return *this; delete [] p; p = obj.p; obj.p = nullptr; return *this; } ~A(){ cout << "Destructor " << endl; delete [] p; } void setData(){ for(int i = 0 ; i < 10 ;i++) p[i] = i*i; } void printData(){ for(int i=0;i<10;i++) cout << p[i] << " "; cout << endl; } }; int main() { A obj ; obj.setData(); obj.printData(); A soj(std::move(obj)); soj.printData(); }
Valgrind检测错误输出
==1198431== Conditional jump or move depends on uninitialised value(s) ==1198431== at 0x1093BC: A::A(A&&) (in /home/pankaj/practice/PracticeC++Advanced/a.out) ==1198431== by 0x109233: main (in /home/alex/practice/PracticeC++Advanced/a.out) ==1198431== Uninitialised value was created by a stack allocation ==1198431== at 0x1091DA: main (in /home/alex/practice/PracticeC++Advanced/a.out)
错误原因与修复方案
错误原因
移动构造函数中,刚构造的新对象成员p是未初始化的随机值,此时执行delete [] p会尝试释放一块不确定的内存,这就是Valgrind报错的根源。
修复方法
删除移动构造函数中多余的delete [] p语句,直接接管源对象的指针即可——新对象的p还未指向任何有效内存,不需要释放。
修改后的移动构造函数:
A(A&& obj){ cout << "Move Constructor" << endl; p = obj.p; obj.p = nullptr; }
补充说明:移动赋值运算符中的delete [] p是合理的,因为赋值操作针对的是已经完成初始化的对象,p此时指向有效的堆内存,需要先释放再接管源对象的资源。
内容的提问来源于stack exchange,提问作者PANKAJ LADE
相关产品推荐
相关产品推荐

