메모리 누수 C++
저는 방금 C++로 코드를 작성했는데, 문자열 조작을 좀 했지만, 제가 Valgrind를 실행했을 때, 메모리 누수 가능성을 보여줍니다.코드를 세분화된 수준으로 디버깅하여 다음과 같은 간단한 C++ 프로그램을 작성했습니다.
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
std::string myname("Is there any leaks");
exit(0);
}
그리고 그 위를 달리는 발그랜드는 다음과 같습니다.
==20943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 26 from 1)
==20943== malloc/free: in use at exit: 360,645 bytes in 12,854 blocks.
==20943== malloc/free: 65,451 allocs, 52,597 frees, 2,186,968 bytes allocated.
==20943== For counts of detected errors, rerun with: -v
==20943== searching for pointers to 12,854 not-freed blocks.
==20943== checked 424,628 bytes.
==20943==
==20943== LEAK SUMMARY:
==20943== definitely lost: 0 bytes in 0 blocks.
==20943== possibly lost: 917 bytes in 6 blocks.
==20943== still reachable: 359,728 bytes in 12,848 blocks.
==20943== suppressed: 0 bytes in 0 blocks.
==20943== Reachable blocks (those to which a pointer was found) are not shown.
==20943== To see them, rerun with: --show-reachable=yes
그리고 나서 우리가 강제로 종료되었다는 생각이 들었습니다(원래 C++ 코드에서도 수행했습니다).이제 문제는 이전 코드가 새 코드의 종료 상태를 대기하기 때문에 프로그램을 종료하고 싶다는 것입니다.예를 들어 이진 a.out의 경우 b.out의 종료 상태를 기다립니다.메모리 누수를 방지할 수 있는 방법이 있습니까? 아니면 프로그램이 이미 종료되고 있기 때문에 메모리 누수를 걱정해야 합니까?
이것은 또한 저에게 또 다른 의문을 제기합니다, 그러한 코드가 해로운가요?
#include<stdio.h>
#include<cstdlib>
int main()
{
char *p=(char *)malloc(sizeof(char)*1000);
exit(0);
}
사용하다return 0;
에 exit(0);
에의 main
의 exit
파괴자의 처형을 우회합니다.
사용을 고집하는 경우exit()
:
#include<iostream>
int main(){
{
std::string myname("Are there any leaks?");
}
exit(0);
}
또한, 당신이 돌아올 때.main
반환된 값이 응용 프로그램의 종료 코드가 됩니다.여러분이 코드를 전달하고 , 종료코전다사음용다니합을면려달하드를 사용하세요.return exitCode;
main()
에 exit
.
그 부분에 관해서는:
이것은 또한 저에게 또 다른 의문을 제기합니다, 그러한 코드가 해로운가요?
네, 왜냐하면 그것은 나쁜 프로그래밍 습관이기 때문입니다.
해제하지 못한 메모리는 OS에서 정리하므로 모든 시스템 메모리와 페이지 파일을 사용하지 않는 한 OS를 손상시키지 않아야 합니다.
하지만 엉성한 코드를 쓰는 것은 습관이 될 수 있으므로, 엉망진창인 상태를 정리하기 위해 OS에 의존하는 것은 좋지 않습니다.
이것은 또한 저에게 또 다른 의문을 제기합니다, 그러한 코드가 해로운가요?
#include<stdio.h> int main() { char *p=(char *)malloc(sizeof(char)*1000); exit(0); }
프로세스가 종료되면 프로세스가 소유한 모든 리소스가 자동으로 닫히기 때문에 최신 운영 체제에서는 문제가 되지 않습니다.
그러나 이는 여전히 잘못된 관행이며, 몇 년 동안 유지보수 작업을 수행한 후 코드가 서서히 변경되면 오류를 찾기 어렵고 미묘하게 발생할 수 있습니다.저는 코드의 일부가 10년 된 프로젝트에서 일했고, 그렇게 함으로써 몇 가지 교훈을 얻었으며, 그 중 일부는 다소 가혹했습니다.따라서 현재 문제가 되지 않더라도 이러한 코드를 작성하는 것은 피하겠습니다.
대부분의 경우, 유지보수성 향상, 도구 점검의 유용성 향상 등 이미 주어진 많은 좋은 이유로 인해 스스로 청소할 가치가 있습니다.
정리해야 하는 다른 기능적 이유가 있는 경우 데이터가 영구 저장소에 저장된 경우에는 선택의 여지가 없습니다. 정리해야 합니다(설계를 다시 고려해야 할 수도 있습니다).
그러나 경우에 따라 그냥 종료하고 "누출"하는 것이 더 나을 수 있습니다.
프로그램이 끝나면 프로세스가 종료됩니다.이렇게 하면 운영 체제는 프로그램에서 할당한 메모리를 복구하며 경우에 따라 훨씬 더 빠르게 복구할 수 있습니다.
각 노드가 동적으로 할당되고 상당한 동적으로 할당된 구조를 갖는 대규모 링크 목록을 생각해 보십시오.이 문제를 해결하려면 각 노드를 방문하여 각 페이로드를 해제해야 합니다(그 결과 다른 복잡한 구조물이 이동할 수 있습니다).
이러한 구조를 실행하기 위해 수백만 개의 메모리 작업을 수행하게 될 수도 있습니다.
사용자가 프로그램을 종료하려고 하면 정크 처리가 발생하기를 10초 동안 기다립니다.그들은 결과에 관심을 가질 수 없습니다. 결국 그들은 프로그램을 그만둘 것입니다.
이 "누설"을 허용하면 운영 체제는 프로세스에 할당된 전체 메모리 블록을 훨씬 더 빠르게 회수할 수 있습니다.구조와 개체 정리는 중요하지 않습니다.
http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
궁극적으로 툴을 올바르게 사용하려면 툴이 제공하는 정보를 이해해야 합니다.
누수를 는 메리누방려다면상반의 합니다.main
부르는 exit
0을에는 0을 할 수 .return
원하는 경우 명령문. 이 경우 프로그램이 0 상태로 종료됩니다.
이것은 또한 저에게 또 다른 의문을 제기합니다, 그러한 코드가 해로운가요?
최신 운영 체제에서는 프로그램이 종료되면 모든 리소스가 자동으로 회수됩니다.하지만 발그랜드와 같은 도구를 사용하여 진정한 문제를 찾는 것은 더 어려워지므로 가능하면 해롭지 않은 메모리 누수도 피하는 것이 가장 좋습니다.
#include<iostream>
using namespace std;
int main()
{
{
std::string myname("Is there any leaks");
}
exit(0);
}
프로세스가 실제로 종료되는 시점에는 main()이 종료되는 시점과 마찬가지로 OS가 애플리케이션에 할당된 모든 리소스를 회수합니다.종료 방법은 중요하지 않습니다. 적어도 동적 메모리와 관련해서는 그렇습니다.
일부 분산 데이터베이스 연결이 열려 있는 경우 exit() 핸들러를 사용하여 종료해야 하며, 바로 가기를 사용하여 강제 종료하면 실행되지 않을 수 있습니다. 하지만 OS 리소스에 관한 한 문제가 없을 수 있습니다.
또한 프로세스 종료로 인해 파일 잠금 및 유사한 것이 사라지지 않을 수 있으므로 항상 해제(수동)해야 합니다.
실행을 중단하고 소멸자를 능가하지 않고 반환 코드를 전달하려면 예외를 던지고 예외에서 반환 값을 추출합니다.main()
.
프로그램이 종료되는 경우, 다음과 같이 할당된 메모리에 대해 걱정할 필요가 없습니다.malloc
또는new
OS가 처리할 것입니다. 프로세스의 가상 주소 공간에 있는 모든 것은 프로세스가 종료될 때 사라집니다.공유 메모리나 명명된 파이프를 사용하는 경우에도 문제가 될 수 있습니다.
다른 의견을 덧붙이자면요.
그러한 코드는 해롭지 않습니다.프로세스가 종료되면 OS가 모든 것을 관리합니다.다른 모든 것은 불안정한 OS를 초래합니다.영구 데이터(파일, ...)의 일관성만 유지하면 됩니다.
조금 더 도발적인 상태로 넘어가자면, 프로그램 종료 시 메모리를 확보하는 것은 위험할 수 있습니다.
- 프로그램 종료 시간이 더 오래 걸립니다(컴퓨터가 종료될 때까지 프로그램이 종료될 때까지 기다리는 것이 짜증난 적이 있습니까?)
- 특히 타사 구성 요소의 경우 올바른 파괴 순서가 항상 사소한 것은 아닙니다(종료 시 충돌할 가능성이 있는 일부 프로그램을 기억합니다).
- 종료 후 OS에서 메모리를 확보하지 못할 수 있습니다.
main
(*) 대신 프로그램을 종료합니다.
당신은 단지 발그린드가 당신에게 특정한 결과를 제공하도록 하기 위해 이것을 위험에 빠뜨리는가?(**)
(*)
#include<iostream>
using namespace std;
std::string myname("Is there any leaks");
int main() {
exit(0);
}
(**) 물론 메모리 분석기의 출력은 "노이즈" 없이 더 유용합니다.디버그 모드에서 종료 시 명시적으로 메모리를 확보하는 것은 어떻습니까?
언급URL : https://stackoverflow.com/questions/9033931/memory-leak-c
'programing' 카테고리의 다른 글
Spring Rest 컨트롤러 상속 (0) | 2023.07.21 |
---|---|
ASP.NET Development Server 대신 IIS에 디버거를 연결하려면 어떻게 해야 합니까? (0) | 2023.07.16 |
원산지/마스터릿 위치는 어떻게 찾고 변경은 어떻게 하나요? (0) | 2023.07.16 |
정수(0)를 잡는 방법은? (0) | 2023.07.16 |
data.tables의 X[Y] join이 전체 외부 join 또는 왼쪽 join을 허용하지 않는 이유는 무엇입니까? (0) | 2023.07.16 |