오늘 우리는 특정 플랫폼에서만 간헐적으로 발생하는 불쾌한 버그의 원인을 발견했습니다. 정리하면 코드는 다음과 같습니다.
class Foo {
map<string,string> m;
void A(const string& key) {
m.erase(key);
cout << "Erased: " << key; // oops
}
void B() {
while (!m.empty()) {
auto toDelete = m.begin();
A(toDelete->first);
}
}
}
이 단순화 된 경우 문제가 명백해 보일 수 있습니다 B. 키에 대한 참조를에 전달 A하면지도 항목을 인쇄하기 전에 제거합니다. (이 경우에는 인쇄되지 않았지만 더 복잡한 방식으로 사용되었습니다.) 이것은 key호출 후 댕글 링 참조 이므로 당연히 정의되지 않은 동작 erase입니다.
이 문제를 해결하는 것은 사소한 일 입니다. 매개 변수 유형을에서 const string&로 변경 했습니다 string. 문제는 :이 버그를 어떻게 처음부터 피할 수 있었습니까? 두 기능이 모두 올바른 것으로 보입니다.
Akey그것이 파괴하려고하는 것을 가리키는 방법은 없습니다 .B에 전달하기 전에 사본을 만들 수A있었지만 값으로 또는 참조로 매개 변수를 취할지 결정하는 것은 수신자의 작업이 아닙니까?
우리가 따르지 않은 규칙이 있습니까?