programing

Cree(): 포인터가 잘못되었습니다.

padding 2023. 10. 30. 20:48
반응형

Cree(): 포인터가 잘못되었습니다.

C를 독학하고 있습니다.제 목표는 쿼리 문자열을 걸어 앰퍼샌드와 등호 위에서 분할하는 C 함수를 만드는 것입니다.나는 발그린드의 이 오류에 걸려있습니다.

==5411== Invalid free() / delete / delete[] / realloc()
==5411==    at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5411==    by 0x804857C: main (leak.c:28)
==5411==  Address 0x420a02a is 2 bytes inside a block of size 8 free'd
==5411==    at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5411==    by 0x804857C: main (leak.c:28)
==5411== 
==5411== 
==5411== HEAP SUMMARY:
==5411==     in use at exit: 0 bytes in 0 blocks
==5411==   total heap usage: 1 allocs, 2 frees, 8 bytes allocated
==5411== 
==5411== All heap blocks were freed -- no leaks are possible
==5411== 
==5411== For counts of detected and suppressed errors, rerun with: -v
==5411== ERROR SUMMARY: 20 errors from 9 contexts (suppressed: 0 from 0)

그리고 역추적:

*** Error in `./leak': free(): invalid pointer: 0x08c1d00a ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767c2)[0xb75f17c2]
/lib/i386-linux-gnu/libc.so.6(+0x77510)[0xb75f2510]
./leak[0x804857d]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7594905]
./leak[0x8048421]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:05 262764     /home/danny/dev/c-qs-parser/leak
08049000-0804a000 r--p 00000000 08:05 262764     /home/danny/dev/c-qs-parser/leak
0804a000-0804b000 rw-p 00001000 08:05 262764     /home/danny/dev/c-qs-parser/leak
08c1d000-08c3e000 rw-p 00000000 00:00 0          [heap]
b757a000-b757b000 rw-p 00000000 00:00 0 
b757b000-b7729000 r-xp 00000000 08:05 1312132    /lib/i386-linux-gnu/libc-2.17.so
b7729000-b772b000 r--p 001ae000 08:05 1312132    /lib/i386-linux-gnu/libc-2.17.so
b772b000-b772c000 rw-p 001b0000 08:05 1312132    /lib/i386-linux-gnu/libc-2.17.so
b772c000-b772f000 rw-p 00000000 00:00 0 
b772f000-b774a000 r-xp 00000000 08:05 1312589    /lib/i386-linux-gnu/libgcc_s.so.1
b774a000-b774b000 r--p 0001a000 08:05 1312589    /lib/i386-linux-gnu/libgcc_s.so.1
b774b000-b774c000 rw-p 0001b000 08:05 1312589    /lib/i386-linux-gnu/libgcc_s.so.1
b774c000-b7750000 rw-p 00000000 00:00 0 
b7750000-b7751000 r-xp 00000000 00:00 0          [vdso]
b7751000-b7771000 r-xp 00000000 08:05 1312116    /lib/i386-linux-gnu/ld-2.17.so
b7771000-b7772000 r--p 0001f000 08:05 1312116    /lib/i386-linux-gnu/ld-2.17.so
b7772000-b7773000 rw-p 00020000 08:05 1312116    /lib/i386-linux-gnu/ld-2.17.so
bfe93000-bfeb4000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

마지막으로 코드는 다음과 같습니다.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {

    //char p[] = "t=quote&k=id&v=10";
    char p[] = "t=quote";

    char* token;
    char* tk; 
    char* s;
    unsigned short int found;

    s = strdup(p);

    if (s != NULL) {
        while ((token = strsep(&s, "&")) != NULL) {

            found = 0;

            printf("TOKEN: %s\n\n", token);

            while ((tk = strsep(&token, "=")) != NULL) {

                printf("TK: %s\n\n", tk);

                free(tk);
            }   

            free(token);
        }   
    }   

    free(s);

    return 0;
}

감사해요.

"사용 가능한" 메모리 주소에 대한 포인터가 아닌 다른 것을 사용할 수 있도록 시도하는 것입니다.어떤 것이 주소라고 해서 그것을 자유롭게 해야 하거나 해야 하는 것은 아닙니다.

당신이 혼동하는 것처럼 보이는 메모리는 스택 메모리와 힙 메모리 두 가지입니다.

  • 스택 메모리는 함수의 라이브 스팬(live span)에 있습니다.너무 커져서는 안 되는 것들을 위한 임시 공간입니다.함수 호출 시main, 선언한 변수에 대한 메모리를 확보합니다(p,token, 등).

  • Heep Memory는 당신이 언제부터 살아있을지 모릅니다.malloc당신이 언제까지free메모리를 쌓는 것보다 훨씬 더 많은 힙 메모리를 사용할 수 있습니다.메모리를 쌓아두는 것처럼 쉬운 일은 아닙니다.

몇 가지 오류가 있습니다.

  • 힙 메모리가 아닌 메모리를 확보하려고 합니다.그러지마세요.

  • 당신은 메모리 블록의 내부를 자유롭게 하려는 겁니다.실제로 메모리 블록을 할당했으면 반환된 포인터로부터만 메모리 블록을 해제할 수 있습니다.malloc. 즉, 블록의 처음부터만.블록의 일부를 안쪽에서 자유롭게 할 수 없습니다.

여기에 있는 당신의 코드에 관해서라면, 당신은 아마도 메모리의 관련된 부분을 다른 곳에 복사하는 방법을 찾고 싶을 것입니다.다른 기억의 한 부분을 말해요또는 원하는 경우 원래 문자열을 수정할 수 있습니다(힌트: char 값 0은 null 터미네이터이며 문자열 읽기를 중지하도록 printf와 같은 함수를 알려줍니다).

편집: malloc 함수는 힙 메모리*를 할당합니다.

"9.9.1 malloc 과 free functions

C 표준 라이브러리는 malloc 패키지로 알려진 명시적인 할당기를 제공합니다.프로그램은 malloc 함수를 호출하여 힙에서 블록을 할당합니다."

~컴퓨터 시스템 : 프로그래머의 관점, 제2판, Bryant & O'Hallaron, 2011

EDIT 2: * C 표준은 실제로 힙이나 스택에 대해 아무것도 지정하지 않습니다.그러나 관련 데스크톱/노트북 컴퓨터에서 학습하는 모든 사람들에게는 프로그램이 저장되고 실행되는 방법에 대해 학습하는 경우 이러한 구분이 불필요하고 혼란스러울 수 있습니다.H2CO3와 같이 AVR 마이크로컨트롤러와 같은 작업을 하고 있다면 임베디드 시스템에 대한 제 경험으로 메모리 할당을 훨씬 넘어선 모든 차이점에 주목할 필요가 있습니다.

당신은 어디서 당신이 필요하다는 생각을 얻었습니까?free(token)그리고.free(tk)? 안 그러시잖아요.strsep()메모리를 할당하지 않고 원래 문자열 내부의 포인터만 반환합니다.물론, 그것들은 에 의해 할당된 포인터가 아닙니다.malloc()(또는 이와 유사),free()그것들은 정의되지 않은 행동입니다.당신은 오직free(s)당신이 전체 스트링을 다 끝냈을 때.

또한 예제에서는 동적 메모리 할당이 전혀 필요하지 않습니다.피할 수 있습니다.strdup()그리고.free()간단히 글을 쓰는 것char *s = p;.

전화하면 안 됩니다.free회답을 받고strsep. 이는 개별적으로 할당된 문자열이 아니라 문자열에 대한 포인터일 뿐입니다.s이미 할당해 놓으셨습니다.s다같이, 당신은 그것을 자유롭게 해야 합니다, 그러나 당신은 그것을 반환 값으로 할 필요가 없습니다.strsep.

언급URL : https://stackoverflow.com/questions/20297524/c-free-invalid-pointer

반응형