2017-12-10 16 views
-1

그래서이 구조체는 파서의 트리로 사용합니다.구조체에 포함 된 문자열 포인터 복사 문제

struct Expr{ 
    struct Expr* a; 
    char* value; 
    struct Expr* b; 
}; 

이와 같이 malloc을 사용하여 초기화합니다.

Expr* initExp(){ 
    Expr* ret; 
    ret = (Expr*)malloc(sizeof(Expr)); 
    ret->a = (Expr*)malloc(sizeof(Expr)); 
    ret->b = (Expr*)malloc(sizeof(Expr)); 
    ret->value = (char*)malloc(sizeof(char)); 
    ret->value = "18killstreak"; 
    ret->a->value = "18killstreak"; 
    ret->b->value = "18killstreak"; 
    return ret; 
} 

지금까지 디버깅 및 트리 인쇄에 필요한 것보다 더 많은 기능을 여기에 작성했습니다. 그래서 Expr * a-> 값을 Expr * 값으로 복사하려고합니다.

strcpy(temp2->value,ret->a->value); 

값은 각각 "18killstreak"및 "x"입니다. 하지만 내 프로그램이이 줄에서 충돌하고 나는이 시점에서 많은 다른 전술을 시도했다.

+0

typedef로 구조를 정의 했습니까? 그렇지 않다면 Expr뿐만 아니라 "struct Expr"을 사용할 필요가 있습니다. –

+0

네 typedef 구조체입니다. Expr Expr; 파일 상단에 –

답변

1

문제는 문자열에 대한 memeory를 관리하지 않으므로 strcpy을 사용할 수 없다는 것입니다. 예를 들어, 당신이있을 때 :

ret->value = (char*)malloc(sizeof(char)); 
ret->value = "18killstreak"; 

이 길이가 0 인 문자열 (단지 NUL)을위한 공간을 allocats하고 정적에 대한 포인터로 할당 된 포인터를 덮어 쓰기 (메모리 누수)을 멀리 던져 상수 문자열 "18Killstreak". 나중에 정적 상수 문자열 (strcpy)을 덮어 쓰려고하면 충돌이 발생합니다.

올바르게 작성하려면 문자열에 대한 메모리를 할당하고 관리해야합니다. 이를 수행하는 가장 쉬운 방법은 각각 에 문자열에 대한 메모리를 소유하고 해당 메모리를 할당/복사/해제하는 데 적절하게 strdup/free을 사용하는 것입니다. 그래서 init 함수가된다 :

free(temp2->value); 
temp2->value = strdup(ret->a->value); 

그리고 당신이 Expr을 무료로 할 때, 당신은 또한에 (첫번째 필요

Expr* ret; 
ret = (Expr*)malloc(sizeof(Expr)); 
ret->a = (Expr*)malloc(sizeof(Expr)); 
ret->b = (Expr*)malloc(sizeof(Expr)); 
ret->value = strdup("18killstreak"); 
ret->a->value = strdup("18killstreak"); 
ret->b->value = strdup("18killstreak"); 

을 나중에 당신이 구조체의 value를 교체 할 때, 당신이 할) 무료 value :

free(exp->value); 
free(exp); 

지금이 하나 isuue는 strdup 표준 C 함수가되지 않는 것입니다 - 그것은 POSIX의 방지 동작입니다 에. 따라서 POSIX 시스템 (예 : Linux 또는 OSX)에서 사용할 수 있지만 POSIX가 아닌 시스템에서는 사용할 수 없습니다. 따라서 직접 정의해야 할 수도 있습니다.

char *strdup(const char *str) { 
    char *rv = malloc(strlen(str) + 1); 
    if (rv) strcpy(rv, str); 
    return rv; 
} 
+0

예! 당신은 strcpy 전에 메모리를 할당해야한다. 그렇지 않다면, 그것은 메모리 침입이다 –

+0

이것은 매우 도움이되었다. 고맙습니다! –