2010-01-06 8 views
2

저는 C 문자열 (char *)에서 작동하는 몇 가지 기본 함수를 작성하기 위해 malloc, realloc 및 free를 사용하고 있습니다. 문자열에서 마지막 문자를 지울 때이 이상한 문제가 발생했습니다. 나는 그런 프로토 타입 함수를 썼다 : 하나 개의 문자에 의해 "DST"문자열을 단축하기로했다동적 메모리 할당 + 문자열 문제 잘림

int string_erase_end (char ** dst, size_t size); 

. 지금까지이 코드와 함께 올라와있다 : 주에서

int string_erase_end (char ** dst, size_t size) 
{ 
    size_t s = strlen(*dst) - size; 
    char * tmp = NULL; 
    if (s < 0) return (-1); 
    if (size == 0) return 0; 
    tmp = (char*)malloc(s); 
    if (tmp == NULL) return (-1); 
    strncpy(tmp,*dst,s); 
    free(*dst); 
    *dst = (char*)malloc(s+1); 
    if (*dst == NULL) return (-1); 
    strncpy(*dst,tmp,s); 
    *dst[s] = '\0'; 
    free(tmp); 
    return 0; 
} 

()를, 내가 문자열을자를 때 (예, 이전에 그들에 malloc을 호출), 나는 이상한 결과를 얻을 수 있습니다. 잘라낼 문자 수에 따라 OK 또는 잘 못된 문자 수가 잘 리거나 조각 모음 오류가 발생합니다.

동적 메모리 할당에 대한 경험이 없으며 항상 C++ 및 std :: string을 사용하여 이러한 모든 더러운 작업을 수행했지만 이번에는 C에서이 작업을 수행해야합니다. 누군가가 나를 도와 주면 감사하겠습니다. 내 실수를 찾아서 바로 잡으십시오. 미리 감사드립니다.

답변

2

첫 번째 strncpy()는 tmp 끝에 '\ 0'을 넣지 않습니다.

또한 이중 복사를 피할 수 있습니다. * dst = tmp;

+2

그런데, (s <0) ...이 절대로 맞지 않는다면. –

+0

올바른 것으로 보입니다. – Hazior

+0

감사합니다. 이제 완벽하게 작동합니다. 다음 번에는 '\ 0'문자를 고려해야합니다. – mingos

2

는 당신의 설명에 따르면, 함수는 문자열의 마지막 n 문자를 삭제하도록되어 :

/* Assumes passed string is zero terminated... */ 
void string_erase_last_char(char * src, int num_chars_to_erase) 
{ 
    size_t len = strlen(src); 

    if (num_chars_to_erase > len) 
    { 
     num_chars_to_erase = len; 
    } 

    src[len - num_chars_to_erase] = '\0'; 
} 
+0

네, 가능한 가장 간단한 방법입니다. 나는 그것이 작동하는 방법에 익숙해 질 필요가 있기 때문에 당분간 메모리 (재) 할당을 사용할 것이다. 그럼에도 불구하고 제안 해 주셔서 감사합니다. 앞으로 유용 할 것입니다. – mingos

1

은 내가 size 매개 변수의 목적을 이해하지 않습니다.

문자열이 처음에 malloc()을 사용하여 할당되는 경우 realloc()을 사용하여 크기를 변경해야합니다. 당신은 일반적으로 1 문자 절단을 위해 할당 된 크기를 변경할 것, "실제 세계"에서

int string_erase_end (char ** dst) 
{ 
    size_t len; 
    char *ns; 

    if (dst == NULL || *dst == NULL) 
    return -1; 

    len = strlen(*dst); 
    if (len == 0) 
    return -1; 

    ns = realloc(*dst, len - 1); 
    if (ns == NULL) 
    return -1; 
    ns[len - 1] = '\0'; 
    *dst = ns; 

    return 0; 
} 

; 즉 자동으로 컨텐츠를 보유하고 적은 작업이 필요합니다 너무 비효율적입니다. 대신 문자열의 길이와 할당 된 크기를 따로 추적합니다. 따라서 문자열이 쉽게 자랄 수 있습니다. 할당 된 공간이 이미있는 한 문자를 추가하는 것은 매우 빠릅니다.

또한 C에서는 반환 값을 malloc()으로 변환 할 필요가 없습니다. 목적이 없으며 버그를 숨길 수 있으므로 그렇게하지 마십시오.

+0

유용한 팁을 가져 주셔서 감사합니다. 이전에 realloc을 시도했지만 문자열의 크기를 줄일 때마다 분할 오류가 발생했습니다 (반면에 문자열에 추가하는 것은 realloc에서 제대로 작동합니다). 이유가 확실하지 않습니다. – mingos