2011-05-05 1 views
8

C로 문자열을 반환하는 메서드를 작성할 때 더 좋은 방법으로 간주되는 것은 무엇입니까? 버퍼 크기를 전달반환하는 C 문자열 처리

:

void example_m_a(type_a a,char * buff,size_t buff_size) 

또는 만들고 적당한 크기의 캐릭터 복귀 :

char * example_m_b(type_a a) 

을 P.S. 당신이 할당 스타일과 중첩 된 기능을 할 수 있도록 버퍼 PTR을 반환에 대해 생각하면 문자열의 크기는 일반적으로의 경우, 특히 버퍼를 전달 즉

char * example_m_a(type_a a,char * buff,size_t buff_size) 
{ 
... 
return buff; 
} 

답변

3

호출하고 크기는 일반적으로 적은 오류가 발생하기 쉬운입니다 "알맞은"크기. 메모리를 동적으로 할당하고 포인터를 반환하면 호출자는 메모리를 해제해야합니다 (할당 된 함수에 따라 메모리에 해당하는 자유 함수를 사용해야 함).

Win32와 같은 대형 C API를 살펴보면 문자열을 반환하는 거의 모든 함수가 호출자가 버퍼와 ​​크기를 전달하는 첫 번째 양식을 사용한다는 것을 알 수 있습니다. 제한된 상황에서만 함수가 반환 값을 할당하는 두 번째 형식을 찾을 수 있습니다 (나는 지금 생각할 수 없다).

1

버퍼가 얼마나 필요한지 결정할 수 있기 때문에 두 번째 옵션을 선호합니다. 종종 발신자가 결정을 내릴 위치에 있지 않습니다.

+0

두 번째! :) – Vern

5

버퍼를 인수로 전달하면이 유형의 코드가 실행할 수있는 대부분의 문제가 해결됩니다.

버퍼에 대한 포인터를 반환하는 경우 할당 방법과 호출자가 버퍼를 해제해야하는지 결정해야합니다. 이 함수는 해제 할 필요가없는 정적 포인터를 반환 할 수 있지만 스레드 안전하지는 않습니다.

+0

다른 언어로하는 방식에 비해 나에게 조금 추한 것 같아요. –

+1

@Roman : 아마도 많은 현대 언어가 진정한 문자열 유형을 가지고 있기 때문일 수 있지만, C 언어는 그렇지 않습니다. C에서는 버퍼가 어디에서 오는지 결정해야합니다. 발신자가 제공 한 경우 발신자가 메모리가 어디서 왔는지 쉽게 알 수 있습니다. –

+0

합창단에게 설교하기. –

1

리턴 코드를 사용하여 패스 버퍼 크기 스타일 또 다른 대안 :

size_t example_m_a(type_a a,char * buff,size_t buff_size) 

제로 복귀 코드는 호출자의 버퍼 적합이었고 충전되었음을 의미

반환. code> 0은 호출자의 버퍼가 너무 작아서 실제로 필요한 크기를 나타내므로 호출자가 버퍼의 크기를 조정하고 다시 시도 할 수 있습니다.

+0

내게 약간의 API가 성공했을 때 문자열의 크기를 반환하거나 실패한 경우 0/-1로 조금 혼란 스러울 수도 있습니다. –

+0

많은 API의 표준에 어긋나지 만 동의하지만, 그것으로 문제를 보지 마라. 물론 반환 코드를 사용하는 대신 size_t * size_needed의 세 번째 인수를 사용하는 것과 같은 다른 맛을 사용하십시오. 필자의 주요 요점은 호출자에게 실패에 대한 옵션을 제공하는 융통성을 제공한다는 생각이었습니다 (re : David Heffernan의 답변). –

0

대부분의 경우 전달 버퍼의 주소와 길이가 가장 좋습니다. 오류가 발생하기 쉽고 메모리 누수에 대해 걱정할 필요가 없습니다. 사실, 일부 긴밀한 임베디드 시스템에서는 힙을 사용하는 것이 전혀 바람직하지 않습니다. 그러나이 기능은 버퍼 오버런을 일으켜 시스템을 손상시킬 수 있으므로 해커가 취약해질 수 있습니다.

할당 된 버퍼를 반환하는 함수를 본 유일한 시간은 xmlDoc에서 XML 텍스트를 생성하는 libxml의 API입니다.