2016-10-30 7 views
-3

I 형 char*문자열이 특정 길이에 도달하면 구조체의 숯불 포인터 요소를 확보 할 수 없습니다

struct TokenizerT_ { 
    char * name; 
}; 

typedef struct TokenizerT_ TokenizerT; 

의 한 요소를 포함하고 정의 된 구조체가 아래 나는 구조체 TokenizerT의 인스턴스를 만들 때 나는 내가 scanf를 사용하여 명령 줄을 통해 문자열을 가지고 아마 t를 해결하는 데 도움이 될 수 어떤 일을 인쇄, 구조체 및 그 요소에 필요한 메모리, 메인 함수에서

TokenizerT *TKCreate(char * ts) { 
    TokenizerT *t= (TokenizerT *) malloc(sizeof(TokenizerT)); 
    t->name= (char *) malloc(sizeof(ts)); 
    strcpy(t->name,ts); 
    return t; 
} 

를 할당 그는

int main(int argc, char **argv) { 
    TokenizerT *token; 
    char input[50]; 
    scanf("%s",input); 
    char *pin = input; 
    token = TKCreate(pin); 

    printf("The address of the tokenizer is %p\n", token); 
    printf("The length of the name is %lu\n", strlen(token->name)); 
    printf("The address of the name is %p\n", token->name); 
    printf("The size of the TokenizerT structure is %lu\n", sizeof(TokenizerT)); 
    printf("The name starting from character 27 is %s\n", token->name + 26); 
    pin=token->name; 
    printf("The whole name is %s\n",pin); 

    TKDestroy(token); 

    return 0; 
} 

문제는 내가 구조체의 유일한 구성원을 확보하는 내 TKDestroy 방법에 의해 발생되고, 발행하지만 난
void TKDestroy(TokenizerT * tk) { 
    free(tk->name); 
    //free(tk); 
} 

프로그램을 실행하고 입력 할 때 왜 확실하지 않다 길이가 26 이하인 문자열은 오류없이 잘 실행됩니다.

enter image description here

그러나 26 자보다 긴 문자열 I 입력하면,이 나는 때문에이 구조체의 숯불 포인터를 해제 할 때 오류가 발생되는 알고

enter image description here enter image description here

발생 전체 struct 인스턴스를 해제 한 행을 주석 처리했습니다. 또한 문자 배열 input의 크기를 변경하면 출력에 아무런 영향을 미치지 않은 것으로 보입니다. 이 오류는 26보다 긴 길이의 문자열을 가리키는 구조체의 char 포인터를 해제하려고 할 때만 발생하는 것으로 보입니다. 일반적으로 할당되지 않았거나 할당되지 않은 메모리를 해제하는 것과 관련이 있다고 들었습니다 액세스가 금지되어 있습니다. 그러나 나는 여전히 26 번째 문자 뒤에 문자의 메모리 주소에 액세스 할 수 있습니다. 왜 이런 경우입니까?

+0

'malloc (sizeof (ts))'는 가리키는 포인터가 아닌 포인터 *'ts '의 크기만큼 메모리를 할당합니다. –

+0

'sizeof (ts)'표현식은 포인터 크기 (일반적으로 플랫폼에 따라 4 또는 8 바이트)와 같습니다. 대신에'strlen (ts) + 1'을 대신 사용하고 싶을 것이다. –

+0

@WeatherVane하지만 왜 문자열의 길이가 프로그램의 포인터를 그냥 비우는 능력에 영향을 줍니까? –

답변

-1

, 당신은 그 일이 있기 때문에 명령을

strcpy(t->name,ts); 

를 제거해야 당신은

 t->name 

에 대한 메모리 할당을 제거하고 또한

 t->name=ts; 

로 변경하려고 할 수 있습니다 이전 명령에 의해 수행됩니다. 그렇다면 오류가 발생합니다. 는 아득히 TKDestroy (..)를 사용하면 명령을 포함 할 수 있습니다 당신은이

free(tk); 

이 도움이 희망입니다 댓글을 달았습니다.