numCheck는 1-1000 사이의 숫자입니다. 이 코드는 charcheck에서 sprintf 결과를 수집 할 때만 segfault를 제공합니다. 결과를 사용하지 않고 sprintf를 사용하면 segault가 발생하지 않습니다. 여기 무슨 일 이니?Sprintf 세그먼트 화 오류
char * numString;
int charcheck = sprintf(numString, "%d", numCheck);
numCheck는 1-1000 사이의 숫자입니다. 이 코드는 charcheck에서 sprintf 결과를 수집 할 때만 segfault를 제공합니다. 결과를 사용하지 않고 sprintf를 사용하면 segault가 발생하지 않습니다. 여기 무슨 일 이니?Sprintf 세그먼트 화 오류
char * numString;
int charcheck = sprintf(numString, "%d", numCheck);
sprintf
에 자신의 메모리를 제공해야합니다. 또한, sprintf
아니라 snprintf
를 사용하지 않는 :
char buf[1000] = {0};
snprintf(buf, 999, ....);
를 또는 동적으로 메모리를 할당 할 수 있습니다
는char * buf = new char[BUFSIZE];
snprintf(buf, BUFSIZE-1, ...);
/* ... */
delete[] buf;
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
을 사용하여 문자열의 끝을 나타낼 수 있습니다.
80과 같은 임의의 값을 사용하는 대신 올바른 크기의 공간을 할당 할 수 있도록 문자로 전달하는 정수의 크기를 확인할 수있는 방법이 있습니까? – syl
@user 아마도 여분의 공간을 할당하는 것이 더 효율적일 것입니다 (계산할 수있는 최대 문자 수는 당신이 저장하고있는 타입으로 계산할 수 있습니다). 왜냐하면 그것을 계산하기 위해서는'if'의 케스케이드가 필요할 것이기 때문입니다. 숫자가 가장 작은 숫자를 계산합니다 (예 : 숫자가 10보다 작은 경우 (항상 '> 0', 마음에 들었을 때) 1 자리, 100보다 작은 경우 2 자리 등). 그러나 스택에 공간을 할당하려면'char numString [9999999999999]'와 같이 무언가를하지 않는 한 일정 시간 (그리고 아주 작은 상수)이 필요합니다. –
당신은 sprintf와의 interal 동작이 귀하의 경우 포인터에 대한 기본 값 NULL을 참조하려고 귀하의 경우와 같은
char numString[50];
int charcheck = sprintf(numString, "%d", numCheck);
결과에 대한 공간을 할당해야합니다.
sprintf
의 첫 번째 매개 변수로 제공된 포인터는 sprintf
이 형식이 지정된 문자열을 작성해야하는 메모리 위치를 가리킬 것으로 예상됩니다.
numString
을 초기화하여 포맷 된 문자열에 할당 한 메모리를 가리 키지 않았습니다. numString
은 초기화되지 않았으므로 아무 곳이나 가리킬 수 있으며 서식있는 출력을 해당 위치에 쓰려고하면 세그멘테이션 오류가 발생합니다.
할 수있는 가장 간단한 것은
char numString[80] = { };
세스, 예수와 Kerrek에 의해 제안, 예를 들어, 위와 같이 배열을 사용하는 것입니다.
sth의 마지막 대답은 좋은 설명이라고 생각합니다. "sprintf의 첫 번째 매개 변수는 sprintf가 형식이 지정된 문자열을 작성해야하는 메모리 위치를 가리킬 것으로 예상됩니다." 그래서 따로 문자열의 메모리 할당을 강제 문자의 배열을 사용에서, 당신은이를 사용할 수 있습니다
char *numstring = (char*) malloc(80);
이가 더 이상 필요 할 때 명시 적으로 할당 된 메모리를 해제하지 수 있도록해야한다.
결과를 수집하지 않을 때 정확하게 작동하는 이유는 무엇입니까? – syl
정의되지 않은 동작입니다. 때로는 정의되지 않은 동작이 예상대로 작동합니다. 이는 최악의 경우입니다. –
왜'sprintf'보다'snprintf'를 권하고 싶습니까? – Kevin