.
Suppose you have the following HalconCpp code to output a string saved in an HTuple:
#include <iostream>
#include <halconcpp/HalconCpp.h>
int main() {
HalconCpp::HTuple text("Hello World");
const char* s = text.S().Text();
std::cout << s << '\n';
return 0;
}
The program contains a sever bug in line 5-7 that I have seen pretty often. Do you catch it immediately?
Follow along to discover the bug for yourself:
set PATH=%HALCONROOT%\bin\x86sse2-win32;%PATH%
cl main.cpp /Zi /EHsc /I%HALCONROOT%/include /link halconcpp.lib /LIBPATH:"%HALCONROOT%/lib/x86sse2-win32
main.exe
The output will be something cryptic like ð☼▲x└
or even a crash.
devenv main.cpp /debugexe main.exe
const char* s = text.S().Text();
To understand what happens, it is often helpful to see what your CPU really executes for a single C++ statement:
const char* s = text.S().Text();
0131C38A lea eax,[ebp-24h]
0131C38D push eax
0131C38E lea ecx,[text]
0131C391 call dword ptr [__imp_HalconCpp::HTuple::S (013BD218h)]
0131C397 mov dword ptr [ebp-10h],eax
0131C39A mov ecx,dword ptr [ebp-10h]
0131C39D mov dword ptr [ebp-14h],ecx
0131C3A0 mov byte ptr [ebp-4],1
0131C3A4 mov ecx,dword ptr [ebp-14h]
0131C3A7 call dword ptr [__imp_HalconCpp::HString::Text (013BD224h)]
0131C3AD mov dword ptr [s],eax
0131C3B0 mov byte ptr [ebp-4],0
0131C3B4 lea ecx,[ebp-24h]
0131C3B7 call dword ptr [__imp_HalconCpp::HString::~HString (013BD228h)]
std::cout << s << '\n';
0131C3BD push 0Ah
0131C3BF mov edx,dword ptr [s]
0131C3C2 push edx
Probably you are not that firm in x86 assembly, but what should be easy to see is the call to HTuple::S
, the call to HString::Text
on the HString
returned by HTuple::S
and then the call to the destructor of the temporary HString::~HString
. From now on every access to the internal data of HString returned by HString::Text
is an access to undefined memory! So the output of s is an output of undefined memory, not of the expected 'Hello World'.
Always assign output from myTuple.S().Text() immediatelly to a memory-managing class like std::string like so:
#include <iostream>
#include <string>
#include <halconcpp/HalconCpp.h>
int main() {
HalconCpp::HTuple text("Hello World");
//const char* s = text.S().Text(); //DO NOT USE
std::string s = text.S().Text();
std::cout << s << '\n';
return 0;
}
btw: Similar to the problem above, one should never assign std::string's c_str()
to a const char*
.