2011-08-25 6 views
10

numCheck는 1-1000 사이의 숫자입니다. 이 코드는 charcheck에서 sprintf 결과를 수집 할 때만 segfault를 제공합니다. 결과를 사용하지 않고 sprintf를 사용하면 segault가 발생하지 않습니다. 여기 무슨 일 이니?Sprintf 세그먼트 화 오류

char * numString; 
int charcheck = sprintf(numString, "%d", numCheck); 

답변

7

sprintf에 자신의 메모리를 제공해야합니다. 또한, sprintf 아니라 snprintf를 사용하지 않는 :

char buf[1000] = {0}; 

snprintf(buf, 999, ....); 

를 또는 동적으로 메모리를 할당 할 수 있습니다

char * buf = new char[BUFSIZE]; 
snprintf(buf, BUFSIZE-1, ...); 
/* ... */ 
delete[] buf; 
+0

결과를 수집하지 않을 때 정확하게 작동하는 이유는 무엇입니까? – syl

+0

정의되지 않은 동작입니다. 때로는 정의되지 않은 동작이 예상대로 작동합니다. 이는 최악의 경우입니다. –

+1

왜'sprintf'보다'snprintf'를 권하고 싶습니까? – Kevin

1

sprintf에 첫 번째 인수는 유효한 버퍼를 가리켜 야합니다. char*이 있지만 쓰레기를 가리 킵니다.

은 당신의 코드를 변경

:

numString이 실제로 유효한 버퍼를 가리키는
char numString[80] = { }; 
int charcheck = sprintf(numString, "%d", numCheck); 

그래서 (이 예에서는 80 개 문자, 모든 요소가있는 0으로 초기화된다). 당신은 당신이 통과 버퍼 크기에서 하나를 빼

const int bufsize = 80; 
char numString[bufsize] = { }; 
int charcheck = snprintf(numString, bufsize - 1, "%d", numCheck); 

주의 사항 :

또한 그래서 당신은 버퍼 오버 플로우를 예방하는 데 도움이됩니다 그것에 당신의 버퍼의 크기를 전달할 수 snprintf를 사용하는 것이 좋은 것 snprintf으로 변경하십시오. 가장 마지막 슬롯을 사용하지 않으려면 NULL을 사용하여 문자열의 끝을 나타낼 수 있습니다.

+0

80과 같은 임의의 값을 사용하는 대신 올바른 크기의 공간을 할당 할 수 있도록 문자로 전달하는 정수의 크기를 확인할 수있는 방법이 있습니까? – syl

+0

@user 아마도 여분의 공간을 할당하는 것이 더 효율적일 것입니다 (계산할 수있는 최대 문자 수는 당신이 저장하고있는 타입으로 계산할 수 있습니다). 왜냐하면 그것을 계산하기 위해서는'if'의 케스케이드가 필요할 것이기 때문입니다. 숫자가 가장 작은 숫자를 계산합니다 (예 : 숫자가 10보다 작은 경우 (항상 '> 0', 마음에 들었을 때) 1 자리, 100보다 작은 경우 2 자리 등). 그러나 스택에 공간을 할당하려면'char numString [9999999999999]'와 같이 무언가를하지 않는 한 일정 시간 (그리고 아주 작은 상수)이 필요합니다. –

0

당신은 sprintf와의 interal 동작이 귀하의 경우 포인터에 대한 기본 값 NULL을 참조하려고 귀하의 경우와 같은

char numString[50]; 
int charcheck = sprintf(numString, "%d", numCheck); 

결과에 대한 공간을 할당해야합니다.

1

sprintf의 첫 번째 매개 변수로 제공된 포인터는 sprintf이 형식이 지정된 문자열을 작성해야하는 메모리 위치를 가리킬 것으로 예상됩니다.

numString을 초기화하여 포맷 된 문자열에 할당 한 메모리를 가리 키지 않았습니다. numString은 초기화되지 않았으므로 아무 곳이나 가리킬 수 있으며 서식있는 출력을 해당 위치에 쓰려고하면 세그멘테이션 오류가 발생합니다.

0

할 수있는 가장 간단한 것은

char numString[80] = { }; 

세스, 예수와 Kerrek에 의해 제안, 예를 들어, 위와 같이 배열을 사용하는 것입니다.

sth의 마지막 대답은 좋은 설명이라고 생각합니다. "sprintf의 첫 번째 매개 변수는 sprintf가 형식이 지정된 문자열을 작성해야하는 메모리 위치를 가리킬 것으로 예상됩니다." 그래서 따로 문자열의 메모리 할당을 강제 문자의 배열을 사용에서, 당신은이를 사용할 수 있습니다

char *numstring = (char*) malloc(80); 

이가 더 이상 필요 할 때 명시 적으로 할당 된 메모리를 해제하지 수 있도록해야한다.

관련 문제