2010-12-08 2 views
1
void *do_chld(void *arg) 
{ 
    char *sub; 
    sub = malloc(255 * sizeof(char)); 

    /* 
     ------ Some Code ---- 
    */ 

    free(sub); 
    pthread_exit((void *)0); 
} 

위 함수는 pthreads로 전달됩니다. 프로그램이 실행되면 세그먼트 오류가 발생합니다. free(sub)로 전화를 걸면 코드가 정상적으로 작동합니다. 나는 이유를 알아낼 수 없다? 스레드에서 메모리를 동적으로 해제 할 수 있습니까? 힙은 주 스레드와 관련된 모든 피어 스레드간에 공유되므로 당신이 /* -- Some Code -- */없이 프로그램을 실행 시도 -pthred가 실행 한 함수로 힙 할당 영역을 해제하면 세그먼트 화 오류가 throw됩니다.

편집 1 전체 코드

void *do_chld(void *arg) 
{ 

    int  new_fd = (int) arg; 
    int  i,n,val; 
    char buf[255]; 
    char *sub; 


    sub = malloc(255 * sizeof(char)); 

    printf("Child thread [%d]: Socket number = %d\n", pthread_self(), new_fd); 

    /* read from the given socket */ 
    n = read(new_fd,buf,100); 
    if(n<0){ 
      fprintf(stderr,"Receieving Failed\n"); 
      exit(2); 
    } 
    //process 
    printf("Received %s \n",buf); 

    val = checkSpelling(buf) ; 
    if(val){ 
     sub = "Correct Spelling"; 
    } 
    else{ 
     sub = "InCorrect Spelling"; 

    } 
    n = 0 ; 

    n = write(new_fd,sub,strlen(sub)); 
    if(n<0){ 
     fprintf(stderr,"Sending Failed\n"); 
     exit(2); 
    } 


    /* close the socket and exit this thread*/ 
    close(new_fd); 
     free(sub); 
    pthread_exit((void *)0); 
} 

답변

3

sub 포인터에 "맞춤법 맞춤법"/ "Incorect 맞춤법"문자열 인 문자열 리터럴을 지정한 다음 free()으로 해제하려고합니다. 문자열 리터럴은 코드에서 정적으로 할당되며 해제 할 수 없습니다.

호출시 기본적으로 sub 포인터는 malloc()으로 할당되지 않은 포인터를 가리 킵니다.

나는 주요 문제는, 그러나, 당신은 아마 문자열의 내용은 당신이 malloc()에서받은 지역에 있도록 을 복사 할 문자열을 수행 할 때, 포인터 할당을 수행하는 것이라고 생각합니다.

편집 : 당신은 strcpy()strdup() 기능을 살펴 가지고 할 수 있습니다

. strncpy()에 익숙하다면 strcpy()이 좋을 것입니다.

strdup()은 대체로 strlen() + malloc() + strcpy()의 조합이며 힙 메모리 영역에 문자열의 복사본을 갖고 싶을 때 일반적으로 free()을 사용하여 해제 할 수 있습니다.

편집 2 : 코드에서

당신은 응답 메시지에 대한 sub 버퍼를 사용하고 그것을 해제 위. 이것이 코드의 최종 동작 일 경우 malloc()free() 호출을 제거하면됩니다.

2

이 나에게 힙 손상 같은 소리?

표시 한 코드가 제대로 보이지만 표시된 코드가 할당 된 메모리 외부의 힙 부분을 덮어 쓸 수 있습니다. 이것은 메모리가 손상된 지점에서 오류를 일으키지 않았고 프로세스가 종료 될 때 오류를 일으키지 않을 수도 있지만 할당 된 메모리를 설명하는 데이터 구조를 매우 쉽게 손쉽게 수정할 수 있습니다. free이 실패합니다.

업데이트 : - 아마도 buf의 끝을지나 작성하여는 사실 실수로 sub 포인터 (일명, 스택 손상)의 값을 수정하는 것이 될 수있다 게시 두 번째 코드를 찾고 있습니다. 그러면 거의 확실하게 free이 실패하게됩니다.

malloc 호출 바로 다음에 sub 값을 확인한 다음 free 직전에 다시 변경하여 변경되지 않았는지 확인하십시오.

업데이트 2 : 스크래치 그 - thkala 정답이 있습니다.

+0

나는/* --- 일부 코드 - */내에서 힙에 액세스하지 않을 것이라고 확신합니다. 참조 용으로 게시하고 있습니다. –

+0

@Eternal - 대신에'sub'의 값이 변경 될 수도 있습니다 - 자세한 내용은 최신 게시물을 참조하십시오. – Justin

0

'sub'는 malloc() 결과의 주소 인 참조를 잃어 버렸기 때문에. 처음에 'sub'는 malloc()의 결과의 시작 주소를 가리 켰습니다. 그러나 'sub'가 "Spell correct"라고하면, 'sub'는 malloc() 메모리를 가리 키지 않습니다. 그 문자열의 시작 주소가되었습니다 - "Corr--"-. 'sub'를 사용하여 malloc() 메모리를 해제하려고하면 컴파일러가 오류를 보냅니다. 왜냐하면 'sub'는 malloc() - 주소를 가리 키지 않을뿐만 아니라 문자열을 해제 할 수 없기 때문입니다 (char arrary) .

당신은 하위가 메모리 자체가 아니라 포인터 값 중 하나임을 놓치지 마십시오.

관련 문제