This C++ code has a significant bug that will cause undefined behavior:
#include <iostream> class A { public: int val; }; void reset(A *p_a) { if (p_a != NULL) { delete p_a; } p_a = new A(); } int main() { A *p_a = new A(); p_a->val = 5; std::cout << "Before reset, p_a->val:" << p_a->val << "\n"; reset(p_a); std::cout << "After reset, p_a->val:" << p_a->val << "\n"; return 0; }
The reset function receives a copy of the pointer p_a, not a reference to it. When you modify p_a inside the function (with p_a = new A()), you're only changing the local copy - the original pointer in main() remains unchanged. What actually happens:
- p_a in main() points to an A object with val = 5
- reset() receives a copy of this pointer
- reset() deletes the original object (memory is freed)
- reset() creates a new object, but assigns it only to the local copy
- The original p_a in main() still points to the deleted memory
- Accessing p_a->val after reset() is undefined behavior (accessing freed memory)
//Reference to pointer void reset(A *&p_a) { if (p_a != nullptr) { delete p_a; } p_a = new A(); // Call with: reset(p_a);
An even better fix is to use smart pointers, which removes the necessity for the reset function:
auto p_a = std::make_unique<A>();
You can detect such problems by enabling AddressSanitizer (ASAN) in Visual Studio:
- Right-click your project → Properties
- Go to Configuration Properties → C/C++ → General
- Set Enable Address Sanitizer to Yes (/fsanitize=address)
- Go to Configuration Properties → C/C++ → Optimization
- Set Optimization to Disabled (/Od) for better debugging
- Set Whole Program Optimization to No
- Go to Configuration Properties → C/C++ → Debug Information Format
- Set to Program Database (/Zi) or Program Database for Edit & Continue (/ZI)
In Eclipse CDT:
- Open your C/C++ project in Eclipse CDT
- Right-click project → Properties
- Navigate to C/C++ Build → Settings
- Under Tool Settings:
- GCC C++ Compiler → Miscellaneous
- GCC C Compiler → Miscellaneous
- Add to "Other flags": -fsanitize=address -g -O1
- Project Properties → C/C++ Build → Settings
- GCC C++ Linker → Miscellaneous
- Add to "Other objects": -fsanitize=address
No comments:
Post a Comment