C++ Builder > 무효 포인터 조작 > 부정값으로의 Free()에 의한 메모리 파괴 > 그 후의 처리로 「무효인 포인터 조작」 | Free() 대신 delete를 사용한다 | 널 포인터 경유의 멤버 함수 호출은 C++ 사양상 미정의 거동
10758 단어 memoryLeakJSONcppBuilderNULL
C++ Builder XE4
발생 조건
원인
TJSONObject *jsonObj;
String jsonKey, jsonValue;
TJSONPair *pairObj;
for(int li=0; li < slread->Count; li++) { // file line index
String jsonText = slread->Strings[li];
// フォルダに使われる"\"の扱いによるエラー対応のため
jsonText = StringReplace(jsonText, L"\\", L"\\\\", TReplaceFlags()<<rfReplaceAll);
jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
for(int pi=0; pi < jsonObj->Size(); pi++) { // pair index
pairObj = jsonObj->Get(pi);
jsonKey = pairObj->JsonString->Value();
jsonValue = pairObj->JsonValue->Value();
// debug_outputDebugString(dbgFormName + L":Load2", String(jsonKey + L":" + jsonValue));
m_json->AddPair(jsonKey, jsonValue);
}
}
jsonObj->Free();
slread->Count가 0일 때, jsonObj에는 부정값이 들어간 채로 된다.
그 부정치를 이용해 Free() 하기 때문에, 메모리가 파괴되어, 그 후의 동작으로 「무효인 포인터 조작」이 발생하고 있는 것 같다.
jsonObj 선언시에 NULL을 넣어두면, Free의 대처는 할 수 있다.
h tps : // s t c ゔ ぇ rf ぉ w. 코 m / 쿠에 s Chion s / 1938735 / Doe s-f Ree Ptr-U-Ptr-S-N-l
7.20.3.2 The free function
...
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs.
See ISO-IEC 9899 .
원래는 선언시에
new TJSONObject()
를 대입하고 있던 코드였지만, 그것은 메모리 누수를 발생한다고 깨닫고 수정했다. 그 수정시 선언시 NULL 대입을 잊고 이번 증상이 나올 때까지 눈치채지 못했다.소감
NULL에서의 Free()의 안전성에 대해 기재하고 있는 블로그가 링크 끊어지고 있었다.
h tp // w w. 게이오시치에 s. jp / ky_ 우비 d / c pp / 펑 게 / 012. HTML
NULL로 초기화되고 있는 포인터를 delete 연산자로 지정하면 아무것도 일어나지 않는 것이 보증되고 있다.
블로그 정보는 수년 만에 사라질 수 있어 유감이다.
Free() 대신 delete 사용
(추기 2017/10/31)
@ 덴미 님의 의견을 바탕으로 찾은 자료에서 아래의 기재를 찾았습니다.
C++ Builder의 Free Method
Note: In C++ code, do not use System::TObject::Free to destroy an object. Use the delete keyword.
C++의 코드에서는 Free()가 아닌 delete를 사용하도록 합니다.
TJSONObject *jsonObj = NULL;
String jsonKey, jsonValue;
TJSONPair *pairObj = NULL;
for(int li=0; li < slread->Count; li++) { // file line index
String jsonText = slread->Strings[li];
// フォルダに使われる"\"の扱いによるエラー対応のため
jsonText = StringReplace(jsonText, L"\\", L"\\\\", TReplaceFlags()<<rfReplaceAll);
jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
for(int pi=0; pi < jsonObj->Size(); pi++) { // pair index
pairObj = jsonObj->Get(pi);
jsonKey = pairObj->JsonString->Value();
jsonValue = pairObj->JsonValue->Value();
// debug_outputDebugString(dbgFormName + L":Load2", String(jsonKey + L":" + jsonValue));
m_json->AddPair(jsonKey, jsonValue);
}
}
delete jsonObj;
null 포인터를 통한 멤버 함수 호출은 C ++ 사양에서 정의되지 않은 동작
@ 사이토와 아츠시 님의 코멘트 에서 널 포인터로부터의 멤버 함수 호출시의 거동에 대해 상세하게 기재되어 있습니다.
정보 감사입니다.
Free() 를 사용하는 것으로 미정의의 거동이 되어, 디버그시에 곤란한 상황이 될 가능성이 있을 것 같습니다. 장래의 트러블 회피를 위해서는 Free()는 사용하지 않게 합시다.
Reference
이 문제에 관하여(C++ Builder > 무효 포인터 조작 > 부정값으로의 Free()에 의한 메모리 파괴 > 그 후의 처리로 「무효인 포인터 조작」 | Free() 대신 delete를 사용한다 | 널 포인터 경유의 멤버 함수 호출은 C++ 사양상 미정의 거동), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/7of9/items/4d47d3f8013c67d630fa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)