2017-01-08 5 views
0

이 프로그램을 실행하려고하면 malloc() 오류가 발생합니다. 메모리가 손상되었습니다. 이 함수에서 오류가 직접 발생하지 않습니다.이 함수 뒤에 malloc()을 시도하면 오류가 발생합니다. 내가 줄을 무료로 제거하면 (ch) 올바르게 작동하므로 부패가 해소 될 때 발생합니다. main()은 함수를 사용하는 방법의 예입니다.할당 된 문자열을 해제 할 때 메모리 손상이

char * makeInt(int val){ 
    char *res = malloc(5); 
    char l [5] = ""; 
    sprintf(l,"%d",val); 
    if(val < 10){ 
    strcat(res,"000"); 
    strcat(res,l); 
    } 
    else if(val < 100){ 
    strcat(res,"00"); 
    strcat(res,l); 
    } 
    else if(val < 1000){ 
    strcat(res,"0"); 
    strcat(res,l); 
    } 
    else if(val < 10000){ 
    strcat(res,l); 
    } 
    res[4] = '\0'; 
    return res; 
} 


    char * makeString(char *ch){ 
    int t = strlen(ch); 
    char *chaine = malloc(t+4); 
    char *nb = makeInt(t); 
    strcat(chaine,nb); 
    strcat(chaine,ch); 
    chaine[t+4] = '\0'; 
    free(ch); 
    return chaine; 
} 

int main(){ 
    char *path = malloc(100); 
// here we do many operations on path, when i call makeString, path contains something 
     path = makeString(path); 
    } 

편집 : 죄송합니다. 게시물을 게시하고 일부 정보를 잊어 버렸습니다. 나는 makeInt()를 추가했다. include에 관해서는, 내 코드에 포함되어 있지만 컴파일되지 않은 include가 메모리 손상을 일으킬 것이라고 생각하지 않는다. 또한 makeString()을 호출하면 path에 문자열이 포함됩니다. makeString()을 코드의 다른 위치에 사용합니다. 내가 자유 (채널) 오류를 추가했을 때,하지만 왜 메모리 손상을 일으킬 메인에 할당 된 메모리를 풀어 이해가 안돼.

strcat(chaine,nb); 

하지만 NUL 바이트를 가져야한다 초기 문자열, 그렇지 않으면 반환되는 어떤 값을 알 수없는 (IE 정의되지 않은 동작)

:

+3

'strcat와 (은 Chaine, NB는)'로 chaine' 내용이 아직 정의되지 않는다. 'path'와 같습니다. – chux

+0

makeString()에서 "ch"의 길이를 결정하고 ... makeString()을 호출하기 전에 초기화되지 않았습니다 ... 위에서 확인한 @chux와 같이 malloc()은 할당 된 메모리를 초기화하지 않습니다 당신은 ... 그것을해야하거나, 대신에 calloc()를 호출해야합니다. – TonyB

+0

게시 된 코드에'# include' 문이 없으므로 컴파일되지 않습니다. (우리 중 많은 사람들은 실제 코드가 무엇을 포함하는지 추측하고 싶지 않습니다.) – user3629249

답변

0

게시 된 코드는 예를 들어 특정 논리 오류를 포함 malloc()에서 반환 된 값은 첫 문자에 NUL 바이트가 있거나 없을 수 있습니다.

게시 된 코드로 인해 seg 오류 이벤트가 발생하는 이유 일 수 있습니다.

(오히려 ALSO malloc()

보다 calloc()를 사용하여이 특정 문제를 해결할 수 makeString()에 매개 변수가 특정 NUL로 초기화되지는 문자열을 종료했습니다. 그래서 strlen()

해당 매개 변수를 전달하는 정의되지 않은 동작입니다

(처음 발견 된 NUL 바이트가 아니라 '경로 배열의 끝을 초과 할 수 있기 때문에)

몇 가지 제안 :

  1. 코드가 사용하는 시스템 기능에 대한 매뉴얼 페이지를 읽으십시오.
  2. 어떤 코드를 통해 (바람직하게는 디버거를 사용하여) 실제로 실행되는지 확인하십시오.

여기에 해당하는 코드가 있습니다.

#include <stdio.h> // printf(), sprintf() 
#include <stdlib.h> // malloc() 
#include <string.h> // strlen(), strcat() 

// prototypes 
char * makeString(char *ch); 


char * makeString(char *ch) 
{ 
    // EDIT: this line was wrong: char *chaine = malloc(sizeof(ch) + 7) // large enough to handle any int value 
    char *chaine = malloc(strlen(ch) + 7); 

    sprintf(chaine, "%4lu", strlen(ch)); 
    strcat(chaine, " "); 
    strcat(chaine, ch); 

    return chaine; // the caller must call `free()` 
} // end function: makeString 


int main(void) 
{ 
    char *path = "my path string"; 
    path = makeString(path); 
    printf("%s\n", path); 
    free(path); 
} // end function: main 

출력은 :

14 my path string 
+0

'char * chaine = malloc (sizeof (ch) + 7); 틀린. – wildplasser

+1

얼마나 malloc인지 다시 생각해보십시오. 포인터의 크기는 이것과 아무 관련이 없습니다. 또한 버퍼 오버 플로우를 피하려면'snprintf'를 사용해야합니다. (int 값은 7을 초과 할 수 있습니다!) –

+0

'malloc() '호출로 문제를 수정했습니다. – user3629249