2014-04-02 1 views
0

코드가 올바르게 컴파일되고 표시되지만 "valgrind"를 실행하면 다음 오류가 표시됩니다. 내가 valgrind에 대한 배경 지식이 없기 때문에 이것을 이해하는 것은 매우 어렵습니다.코드 및 가능한 솔루션의 메모리 오류

Invalid write of size 1 
==14657== at 0x4EAE10C: _IO_default_xsputn (genops.c:480) 
==14657== by 0x4E7CF81: vfprintf (vfprintf.c:1630) 
==14657== by 0x4EA3813: vsprintf (iovsprintf.c:43) 
==14657== by 0x4E85A06: sprintf (sprintf.c:34) 
==14657== by 0x400622: copy_id_name (assign2a.c:12) 
==14657== by 0x40065E: main (assign2a.c:21) 
==14657== Address 0x51f204b is 0 bytes after a block of size 11 alloc'd 
==14657== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==14657== by 0x400600: copy_id_name (assign2a.c:11) 
==14657== by 0x40065E: main (assign2a.c:21) 
==14657== 

실제 오류 및이 오류를 제거하는 방법을 알려주세요.

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

/** Returns a pointer to allocated memory containing string in form "<id>=<name>" */ 
char *copy_id_name(const char *id, const char *name) { 
    char *ptr = NULL; 
    size_t len; 
    // Compute required length 
    len = strlen(id) + strlen(name); // [sic] 
    ptr = malloc(len-2); // [sic] 
    sprintf(ptr, "%s=%s", id, name); 
    return ptr; 
} 


int main(int argc, char *argv[]) 
{ 
    char *ptr; 

    if (argc > 2) { 
    ptr = copy_id_name(argv[1], argv[2]); 
    } else { 
    ptr = copy_id_name("666", "badname"); 
    } 
    printf("result: [%s]\n", ptr); 
    return 0; 
} 
+0

valgrind 옵션은 무엇입니까? – vad

답변

3

당신이 C에서 문자열이 strlen에 의해보고 된 것보다 실제로 한 문자 이상 기억해야 할 우선. 그 여분의 문자는 특수 문자 ('\0')에 사용되어 문자열의 끝임을 함수에 알려줍니다.

문제는 여기에 당신이 idname 문자열의 결합 길이보다 두 바이트적게 할당하고,이 자합니다 ('=''\0' 종료)을 추가로 다음 그 문자열을 결합한다는 것입니다. 즉, 할당 된 메모리의 끝을 넘어 쓸 것입니다.

+0

malloc (len)에서 malloc (len + 2)로 변경 한 후에도 valgrind는 위에서 언급 한 것과 같은 오류를 표시합니다. ( – akshitonline

+1

@ user3425724 크기를 인쇄하는 디버그'printf' 호출을 추가하기 만하면됩니다. 예제에서와 같이 길이가''''666''과''badname ''인 문자열 인 경우 (예 :'printf ("% d 바이트를 할당 \ n", len + 2);)) –

+0

잘못된 파일이 실행 중입니다. 문제가 해결되었습니다. 감사합니다 :) – akshitonline

2
ptr = malloc(len-2); 

필요 이상으로 4 바이트를 할당합니다. strlen()은 문자열의 길이를 나타내며 널 종료를 계산하지 않습니다. 그러나 널 종료를위한 공간을 할당해야합니다. 단순히 -2에서 +2로 변경하십시오.

+0

malloc (len)에서 malloc (len + 2)으로 바꾼 후에도 valgrind는 다음과 같은 오류를 표시합니다. 위에서 언급 한 :( – akshitonline

+0

문제가 해결되었습니다. 감사합니다 :) – akshitonline