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)
The Fix: Pass the pointer by reference using a pointer-to-pointer or reference-to-pointer:
//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