valgrind - 주소 ---- 크기가 8인 블록이 할당된 후 0바이트입니다.
먼저, 비슷한 질문이 있었던 것으로 알고 있습니다.하지만, 저는 정말 원시적인 C 데이터 유형에 대해 좀 더 일반적이고 간단한 질문을 하고 싶습니다.자, 여기 있습니다.
인main.c
이 문자열을 채우는 함수를 호출합니다.
int
main (int argc, char *argv[]){
char *host = NULL ;
char *database ;
char *collection_name;
char *filename = "";
char *fields = NULL;
char *query = NULL;
...
get_options(argc, argv, &host, &database, &collection_name, &filename,
&fields, &query, &aggregation);
안에서.get_options
:
if (*filename == NULL ) {
*filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+4);
strcpy(*filename, *collection_name);
strcat(*filename, ".tde"); # line 69
}
내 프로그램은 잘 작동하지만, 발그린드는 내가 잘못하고 있다고 말합니다.
==8608== Memcheck, a memory error detector
==8608== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8608== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8608== Command: ./coll2tde -h localhost -d test -c test
==8608==
==8608== Invalid write of size 1
==8608== at 0x403BE2: get_options (coll2tde.c:69)
==8608== by 0x402213: main (coll2tde.c:92)
==8608== Address 0xa2edd18 is 0 bytes after a block of size 8 alloc'd
==8608== at 0x4C28BED: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8608== by 0x4C28D6F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8608== by 0x403BBC: get_options (coll2tde.c:67)
==8608== by 0x402213: main (coll2tde.c:92)
오류를 설명해 주시겠습니까?Address 0xa2edd18 is 0 bytes after a block of size 8 alloc'd
이 문제를 어떻게 해결할 수 있습니까?
strcpy
null 종료 문자를 추가합니다.'\0'
공간을 할당하는 것을 잊었습니다.
*filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5);
5자의 공간을 추가해야 합니다. 4자:".tde"
접미사, 그리고 다음을 위한 하나 더.'\0'
터미네이터현재 코드는 4개만 할당하므로 새 파일 이름에 할당한 블록 바로 다음 공간에 마지막 쓰기가 수행됩니다(즉, 0바이트 이후).
참고: 코드에 공통적인 문제가 있습니다. 코드는 다음의 결과를 할당합니다.realloc
다시 할당되는 포인터에 직접 연결합니다.이것은 다음과 같은 경우에 좋습니다.realloc
성공했지만 실패하면 메모리 누수가 발생합니다.이 오류를 수정하려면 다음 결과를 저장해야 합니다.realloc
별도의 변수에서, 그리고 그것을 확인합니다.NULL
값을 다시 할당하기 전에*filename
:
char *tmp = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5);
if (tmp != NULL) {
*filename = tmp;
} else {
// Do something about the failed allocation
}
직접 할당*filename
메모리 누수를 만듭니다. 포인터가*filename
아래에서 지적한 바와 같이 장애가 발생하면 덮어쓰게 되어 복구할 수 없게 됩니다.
클래스를 변경하고(필드를 추가하여 크기를 변경) 헤더가 포함된 모든 소스를 다시 작성하지 않았기 때문에 이 메시지가 표시되었습니다.그래서 일부 모듈은 여전히 이전 크기를 사용하려고 했습니다.
이 문제에 대해 배운 내용을 공유합니다.
첫째, 오류 메시지는 특히 단어를 오해하게 합니다.after
처음에, 나는 그것이 무슨 일이 일어난다는 것을 의미한다고 생각했습니다.after
(시간 수준에서) 메모리 블록을 할당했습니다.그러나 실제로는 임의의 메모리 주소에서 데이터를 읽고 있다는 의미입니다.그리고 그 무작위 기억은 단지after
(주소 공간에서) 할당한 메모리 블록입니다.
제 경험에 따르면, 일반적으로 배열 인덱스가 범위를 벗어날 때 발생합니다.
다음과 같은 간단한 데모 코드를 살펴보겠습니다.
#include <stdlib.h>
#include <stdio.h>
int main() {
int *x = (int*)malloc(sizeof(int));
x += 3; // x now points to invalid memory(some random location)
printf("%d\n", *x); // read from an invalid location of memory
*x = 4; // write to an invalid location of memory
free(x - 3);
return EXIT_SUCCESS;
}
실행 시 다음과 같은 오류 메시지가 표시됩니다.valgrind
메모 확인
==4720== Invalid read of size 4
==4720== at 0x1091AC: main (memo2.c:7)
==4720== Address 0x4a5204c is 8 bytes after a block of size 4 alloc'd
==4720== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4720== by 0x10919E: main (memo2.c:5)
==4720==
0
==4720== Invalid write of size 4
==4720== at 0x1091C5: main (memo2.c:8)
==4720== Address 0x4a5204c is 8 bytes after a block of size 4 alloc'd
==4720== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4720== by 0x10919E: main (memo2.c:5)
언급URL : https://stackoverflow.com/questions/27636306/valgrind-address-is-0-bytes-after-a-block-of-size-8-allocd
'programing' 카테고리의 다른 글
Spring Cloud Security와 함께 OAuth2 "Token Exchange"를 구현하는 방법 (0) | 2023.07.22 |
---|---|
NHibernate에서 드라이버를 생성할 수 없습니다.드라이버.Oracle Data Client 드라이버 (0) | 2023.07.22 |
일부 기준에 따라 행을 반환하고 조건과 일치하는 행이 없으면 mariadb sql의 모든 행을 반환합니다. (0) | 2023.07.22 |
Redis - 클러스터를 사용하여 데이터 손실 방지(가십 프로토콜 사용) (0) | 2023.07.22 |
스프링에서 주석을 통해 생성자에 매개변수 주입 (0) | 2023.07.22 |