programing

다른 기능에 할당 된 여유 메모리?

nasanasas 2020. 11. 18. 09:12
반응형

다른 기능에 할당 된 여유 메모리?


나는 C를 배우려고 노력하고 있으며 현재 기본 스택 데이터 구조를 작성하려고 시도하고 있지만 기본 malloc/ free올바른 것 같지 않습니다 .

다음은 제가 사용한 코드입니다 (전체 코드가 아닌 특정 문제를 설명하기 위해 여기에 작은 부분을 게시하고 있지만에서이 예제 코드를 실행하여 오류 메시지가 생성되었습니다 valgrind)

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

typedef struct Entry {
    struct Entry *previous;
    int value;
} Entry;

void destroyEntry(Entry entry);

int main(int argc, char *argv[])
{
    Entry* apple;
    apple = malloc(sizeof(Entry));
    destroyEntry(*(apple));
    return 0;
}

void destroyEntry(Entry entry)
{
    Entry *entry_ptr = &entry;
    free(entry_ptr);
    return;
}

내가 통해 그것을 실행하는 경우 valgrind--leak-check=full --track-origins=yes, 나는 다음과 같은 오류가 발생합니다 :

==20674== Invalid free() / delete / delete[] / realloc()
==20674==    at 0x4028E58: free (vg_replace_malloc.c:427)
==20674==    by 0x80485B2: destroyEntry (testing.c:53)
==20674==    by 0x8048477: main (testing.c:26)
==20674==  Address 0xbecc0070 is on thread 1's stack

이 오류는 destroyEntry함수가 main에 명시 적으로 할당 된 메모리를 수정할 수 없음을 의미한다고 생각합니다 . 맞습니까? 다른 함수에 free할당 한 메모리 만 사용할 수없는 이유는 무엇 main입니까? (그리고이 동작은 어떻게 든 main에 한정됩니까?)


매개 변수를 함수에 전달할 때마다 복사본이 만들어지고 함수는 해당 복사본에서 작동합니다. 따라서 귀하의 경우 free에는 원본 개체의 복사본을 시도하고 있지만 의미가 없습니다.

포인터를 받도록 함수를 수정 한 다음 free해당 포인터에서 직접 호출하도록 할 수 있습니다 .


이것은 값으로 전달됩니다. 즉, 복사본이 생성되므로 로컬 변수가있는 메모리를 해제하려고 entry합니다. 참고 entry이 프로그램이 범위를 벗어나면 자동으로 해제됩니다있는 자동 저장 기간 및 메모리 객체입니다 destroyEntry기능.

void destroyEntry(Entry entry)
{
    Entry *entry_ptr = &entry;
    free(entry_ptr);
    return;
}

함수는 포인터를 가져야합니다 (참조로 전달).

void destroyEntry(Entry *entry)
{
    free(entry);
}

Then instead of destroyEntry(*(apple)); you just call destroyEntry(apple);. Note that if there is no other functionality connected with destroyEntry function, it's redundant and it's better to just directly call free(apple).


The other answers here point out the main problem -- because you dereference your apple when you call destroyEntry in main(), it passes by reference, creating a copy.

Even once you know your problem, it helps to go back to the error and try to connect the text of what you're seeing to the problem, so that the next time it comes up you might be more likely to figure it out quickly. I find C and C++ errors can seem maddeningly ambiguous sometimes.

Generally, when I'm having trouble freeing pointers or deleting objects, I like to print out addresses, especially right when I allocate it and right when I try to free it. valgrind already gave you the address of the bad pointer, but it helps to compare it to a good one.

int main()
{
  Entry * apple;
  apple = malloc(sizeof(Entry));
  printf("apple's address = %p", apple);  // Prints the address of 'apple'
  free(apple);   // You know this will work
}

After doing that, you'd notice the printf() statement gave you an address something like 0x8024712 (just making up an address in the right general range), but your valgrind output gave 0x4028E58. You'd notice they're in two very different places (in fact, "0x4..." is on the stack, not the heap where malloc() allocates from, but I'm assuming if you're just starting out that's not a red flag for you yet), so you know you're trying to free memory from the wrong place, hence "invalid free()".

So from there you can say to yourself "Okay, somehow my pointer is getting corrupted." You already boiled down your problem to a small, compilable example, so it won't take you long to solve it from there.

TL;DR - when running into pointer-related errors, try printing the addresses or finding them in your favorite debugger. It often at least points you in the right direction.

None of this is to discourage posting your question on Stack Exchange, of course. Hundreds of programmers will likely benefit from your having done so.

참고URL : https://stackoverflow.com/questions/11071190/free-memory-allocated-in-a-different-function

반응형