2014-04-21 3 views
0
char * stft (const char *fmt, ...) { 

    va_list items; 
    char *out; 
    int magic = 0; // <-- here magic? 

    va_start (items, fmt); 
    vsprintf (out, fmt, items); 
    va_end (items); 

    return out; 

} 

사용 :이상한 행동 같은

char *str = stft ("%s-%s %s", a, b, c); 

이 작동하고 해결책? 미사용 "마법"변수를 삭제하는 경우 - 반환 문자열 뒤에 분할 오류가 발생했습니다. 무엇이 잘못 되었나요?

$ gcc를 --version GCC (데비안 4.4.5-8) 4.4.5

$ 끝나면 uname -a 리눅스 깊은 역 (스퀴즈) 2.6.32-5-686 # 1 SMP (금) 월 10 08:33:48 UTC 2013 i686 GNU/Linux

+0

질문과 관련이 없지만 '출력'을 초기화 할 항목이 없어야합니까? – guest

+0

@guest : 질문과 관련이 없습니다. 문제는 'out'이 초기화되지 않아 충돌이 발생한다는 것입니다. –

+0

좋은 sleuthing. thanks – guest

답변

1

초기화되지 않은 포인터 out에 쓰려고합니다. 그래서 당신이 추락합니다. 잘못 정의 된 동작입니다. 마술은 우연의 일치입니다. 행동을 더 잘 정의하지는 않습니다.

vsnprintf()를 사용하는 것이 가장입니다 : 유사한

char *out = malloc(256); 
... 
vsnprintf(out, 256, fmt, items); 
... 
return out; 

또는 뭔가.

개선 할 수 있습니다. 예를 들어,

char *stft(const char *fmt, ...) 
{ 
    va_list items; 

    va_start(items, fmt); 
    int length = vsnprintf(0, 0, fmt, items); 
    va_end(items); 
    char *out = malloc(length+1); 
    if (out != 0) 
    { 
     va_start(items, fmt); 
     vsnprintf(out, length+1, fmt, items); 
     va_end(items); 
    } 

    return out; 
} 

호출 코드에서 할당 된 메모리를 해제해야합니다.

+0

>>> 호출 코드에서 할당 된 메모리를 해제하십시오. 무료 사용을 위해() 솔루션을 원했고 이상한 행동이 발견되었습니다. – Deep

+0

죄송합니다. 귀하의 의견을 이해할 수 없습니다. 함수가 메모리를 할당하지 않도록하려면 두 가지 방법이 있습니다. 더 좋은 선택은 버퍼 ('char * buffer')와 그 길이 ('size_t buflen')를 전달한 다음,'vsnprintf (buffer, buflen, fmt, items)'를 사용하는 것입니다. 더 나쁜 선택은 함수와'vsnprintf (buffer, sizeof (buffer), fmt, items);에서'static char buffer [256];'이다. 이것은 동시성 문제가 있으며, 함수를 두 번 호출 할 수없고 명시 적 복사없이 형식화 된 두 문자열을 모두 유지할 수 없다는 것을 의미합니다. 이 두 가지 모두 버퍼가 너무 짧을 수 있습니다. –

+0

솔루션을 제공해 주셔서 감사합니다! 이제는 stft()의 단일 호출과 현재 stft() 컨텍스트에 대한 하나의 호출 재 할당 버퍼 길이에 대해서만 전역 버퍼를 사용합니다. 감사합니다! – Deep