[This is CS50 2024] After Week4 - 메모리 #License

moonstrnck·2024년 2월 22일

CS50

목록 보기
12/13

[CS50 Practice - #License]

License

Learning Goals

  • 파일 및 파일 포인터 작업 연습
  • 문자열 및 배열에 대한 추가 작업
  • debug50으로 디버깅
  • Valgrind를 사용하여 메모리 누수 확인

Background

AI로 강화된 번호판 인식 기술을 개발하는 회사에서 근무한다고 가정해 보겠습니다. 기술을 개발하면서 실제 자동차 번호판 번호를 테스트 데이터로 사용하고 싶을 수도 있습니다. 분석하려는 번호판이 포함된 텍스트 파일이 있으므로 먼저 해당 텍스트 파일에서 읽고 자동차 번호판을 인쇄하여 파일 읽기 논리를 테스트해 봅니다. 그러나 프로그램을 실행하면 마지막 숫자만 8번 인쇄됩니다! 무엇이 잘못되었나요?

Demo

Demo 보기

Getting Started

  1. GitHub 계정을 사용하여 cs50.dev에 로그인합니다.
  2. 터미널 창 내부를 클릭하고 cd를 실행합니다.
  3. 코드 공간에 License.zip이라는 zip을 다운로드하려면
    wget https://cdn.cs50.net/2022/fall/labs/4/license.zip을 실행하고 Enter를 누르세요. 다음 URL 또는 해당 문제에 대한 기타 문자 license.zip사이의 공백을 간과하지 않도록 주의하세요 !
  4. 이제 실행하여 unzip license.zip이라는 폴더를 만듭니다.
  5. 더 이상 ZIP 파일이 필요하지 않으므로 rm License.zip을 실행하고 프롬프트에서 “y”와 Enter를 차례로 입력하면 됩니다.

Implementation Details

파일을 열면 plates.txt실제로 8개의 서로 다른 자동차번호판 번호가 있음을 알 수 있습니다. 이 문제를 일으키는 배포 코드에 몇 가지 오류가 있습니다. 코드를 살펴보는 것부터 시작해 보겠습니다.

argv[1]번호판이 포함된 텍스트 파일이어야 하므로 먼저 명령줄 인수를 확인합니다 . 그런 다음 플레이트 번호의 길이가 6 char초이고 NUL 종결자를 위한 공간을 절약해야 하므로 길이가 7인 문자 배열을 만듭니다. 이제 8개의 번호판 번호를 저장하기 위해 char *'s(문자 포인터,string s!라고도 함 ) 배열을 만듭니다 . string외부 텍스트 파일에 대한 파일 포인터를 만들고, 각 배열 요소의 인덱스를 보유하는 변수를 만든 다음, 파일을 읽고 플레이트 번호를 배열에 저장하기 시작합니다. 마지막으로, 이 작업이 올바르게 수행되었는지 테스트하기 위해 배열의 값을 인쇄합니다.

그러나 이 코드를 컴파일하고 실행해 보면 뭔가 분명히 잘못된 것이 있습니다. 적절한 수정을 해야 합니다!

Debugging

배열에 실제로 어떤 값이 추가되는지 자세히 살펴보세요. debug50으로 실험하여 배포 코드의 오류를 찾을 수 있습니다.

Hints

  • 플레이트 배열의 각 요소에 할당되는 변수 버퍼는 정확히 무엇을 보유합니까?
  • 플레이트 배열은 char * 또는 문자열 포인터의 배열입니다.
  • 그렇다면 char 배열 버퍼를 char *에 할당하면 실제로 어떤 일이 발생할까요?

번호판 번호를 라이센스 어레이에 복사하는 더 좋은 방법이 있습니까?

Hints

  • strcpy가 여기서 유용할까요?
  • 데이터를 포인터에 복사하면 해당 데이터는 어디로 가나요?
  • 여기에 malloc이 필요합니까?

Checking for Memory Leaks

프로그램이 제대로 작동하는 것 같으면 valgrind를 실행하여 메모리 누수가 없는지 확인하세요.

valgrind ./license plates.txt

다음과 같은 결과가 나올 수 있습니다.

==24478== HEAP SUMMARY:
==24478==     in use at exit: 528 bytes in 9 blocks
==24478==   total heap usage: 10 allocs, 1 frees, 4,624 bytes allocated
==24478== 
==24478== 56 bytes in 8 blocks are definitely lost in loss record 1 of 2
==24478==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24478==    by 0x109207: main (license.c:30)
==24478== 
==24478== 472 bytes in 1 blocks are still reachable in loss record 2 of 2
==24478==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24478==    by 0x4A086CD: __fopen_internal (iofopen.c:65)
==24478==    by 0x4A086CD: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==24478==    by 0x1091CD: main (license.c:20)
==24478== 
==24478== LEAK SUMMARY:
==24478==    definitely lost: 56 bytes in 8 blocks
==24478==    indirectly lost: 0 bytes in 0 blocks
==24478==      possibly lost: 0 bytes in 0 blocks
==24478==    still reachable: 472 bytes in 1 blocks
==24478==         suppressed: 0 bytes in 0 blocks
==24478== 
==24478== For lists of detected and suppressed errors, rerun with: -s
==24478== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

여기에는 수정해야 할 두 가지 종류의 메모리 오류가 있는 것 같습니다.

Hints

  • 줄 번호는 다를 수 있지만 여기서는 30번 줄(malloc과 관련된 문제)과 20번 줄(fopen과 관련된 문제)의 main에 메모리 문제가 있는 것 같습니다. 유통 코드에 무엇이 누락되었을 수 있나요?

0개의 댓글