2011-09-15 2 views
1

참고 : "C++? use std :: string!"에 대한 설명을 숨기십시오.. 이 질문은 C 문자열을 사용하지만 일반적으로 문자열보다 메모리 관리에 관한 것입니다.여기서 malloc 된 포인터를 반환하면 "HEAP CORRUPTION"이 무료로 제공되는 이유는 무엇입니까?

나는이 기능이 기능은 (strclone에) 새로운 포인터를 할당하는 작업을해야

char* strclone(char* src) 
{ 
    char* dst = (char*)malloc(strlen(src+1)); 
    strcpy(dst,src); 
    return dst; 
} 

, 그것에 SRC 문자열을 쓰고, 새로운 문자열의 주소를 반환 있습니다. 문자열이 free D 경우

그러나, 나중에 프로그램에 약간의 시간 :

str = strclone(some_str_variable);  
// ..code.. 
free(str) ; //! ERROR! 

오류가 읽

디버그 오류! 프로그램 : C : \ ... 힙 손상 감지 : 0x090CC448의 일반 차단 (# 39713) 이후. CRT가 응용 프로그램이 힙 버퍼의 끝 뒤에서 메모리에 쓰는 것을 감지했습니다.

프로그램에서 free(str)을 호출하는 라인에서 오류가 발생합니다. str을 다음과 같이 변경하면 :

str = (char*)malloc(strlen(some_string_variable) +1); 
strcpy(str, some_string_variable) ; 
//... 
free(str) ; //fine now 

그러면 프로그램이 완벽하게 작동합니다.

strclone 기능이 예상대로 작동하지 않는 이유는 무엇입니까?

+1

문제를 나타내는 ** 전체 ** 예를 게시 할 수 있습니까? –

+1

@Oli : 한 줄이면 충분하지만 걱정하지 마세요! –

답변

15

나는 문제가 당신이 strlen에 대한 호출에, 당신은

strlen(src) + 1 

이의

strlen(src + 1) 

대신 쓴 것을

(char*)malloc(strlen(src+1)); 

공지 사항을 서면으로 작성했습니다 것을 믿습니다 첫 줄에 "한 문자를 시작하는 문자열의 길이는입니다."이며, 문자열의 길이에서 1을 뺀 값 (또는 문자열이 비어있는 경우 전체 가비지)입니다. 두 번째 것은 원하는 문자열입니다. 문자열의 길이와 널 종결 자의 길이입니다. 당신이 줄을

strcpy(dst,src); 

를 다음 첫 번째 버전을 사용하는 경우, 당신은 지칠대로 지친 정의되지 않은 행동으로 이어지는, 버퍼의 끝을지나 서면으로 종료됩니다. 사실, 블록을 해제하려고 할 때 힙 손상 오류가 나타났습니다. 블록이 실제로 힙을 손상 시켰기 때문에 의미가 있습니다!

괄호에서 +1을 이동하여 수정했는지 확인해보십시오.

또는 대부분의 컴파일러는 위의 함수가 수행하려고하는 것과 정확히 일치하는 strdup이라는 비표준 함수를 제공합니다. 대신에 이것을 사용하는 것이 좋습니다.

희망이 도움이됩니다.

+6

아 .. 사람. 나는 지금 집에 갈거야. – bobobobo

+0

"일반적인 문자열보다 메모리 관리에 관한 것"이라는 주장에도 불구하고, 이것은 실제로 C 문자열 ('strlen') 문제로 밝혀졌습니다. 그래서 C 문자열은 너무 위험합니다. 모든 사실들이 다른 방향을 가리킬지라도 당신이 그것을 올바르게하고 있다는 것을 확신하는 것은 너무 쉽습니다. – MSalters

3

strlen(src+1)strlen(src)+1과 같지 않습니다. 따라서 strcpy을 수행 할 때 배열의 경계를 두 요소로 덮어 쓰게됩니다.

그래서 다음과 같은 내용이 합당하다고 생각합니다. C++? std::string을 사용하십시오!

0

이 시도 :

malloc(strlen(src)+1);

0

을 당신이

char* dst = (char*)malloc(strlen(src) + 1); 

대신

char* dst = (char*)malloc(strlen(src+1)); 
0
입력 한 것으로 판단 실제로 할당 된 과거의 기록되기 때문에 오류가 발생

기억. 이 귀하의 malloc 라인을 변경 :

char* dst = (char*)malloc(strlen(src)+1); 

을하기 때문에 원래의 구현에, 당신은 1 포인터를 진행하고 있으며, 당신은() 나 strlen에있는 당신에게 현악기의 아이폰에 줄 것이다 되었 1. 마지막에 NULL이 필요하기 때문에 실제로는 2가 벗어난 것입니다.

관련 문제