2015-01-08 2 views
0

저는 C에서 매우 익숙합니다. 지금 프로그램에서 사용자가 문자 배열 (문자열)을 프로그램 이름 형식으로 입력하도록 요구하는 중입니다. 이 이름을 배열에 저장 한 다음이 배열을 다른 함수에 전달합니다. 지금배열에 사용자 입력 문자열이있어서 버퍼 오버플로가 발생했습니다.

, 나는 이것이 내가 사용자가 입력 할 수 있습니다 모르겠어요으로, 동적으로 할당 된 배열이며, 여기에 달성하기 위해 시도했습니다 최신 방법은 어떻게 그 일을 해요 :

char *process; 
process = (char *)malloc(sizeof(char) * (i+1)); 

그때 printf 자신의 입력을 사용자의 입력을 요청하고 확인로 이동 : 나는 scanf() 실제로 작동하고 fgets()가 원인이 모두 scanf()fgets()을 시도했습니다

printf("Enter process name: "); 
scanf("%79s", &process); // take input, load into array 
// fgets(process, sizeof(ARRAY_SIZE), stdin); 
printf("You entered: %s\n", process[i]); 

프로그램 내 printf 문을지나 완전히 뛰어 본으로 진행합니다 : 프로그램이 Segmentation Fault로 종료 어디

for(i = 0; i < ARRAY_SIZE; i++) 
    printf("process = %s\n", process[i]); 

합니다. 나는 이것이 할당 된 버퍼를 오버런하는 사용자 입력 때문이라는 것을 이해합니다.

gdb에서 프로세스의 값을 인쇄 할 때 가비지가 채워집니다 (C가 값을 추가하기 전에 C가 배열을 초기화하는 방법입니다). scanf("%79s", &process) 바로 뒤에는 쓰레기를 교체하는 대신 쓰레기 시작 부분에 입력 한 내용이 표시됩니다. 내 질문은 버퍼를 오버런시키지 않도록 배열을 "비우는"방법이다. 3 일 동안 여러 가지 방법을 시도해 보았습니다. 배열을 제대로 초기화하는 방법에 대한 세부적인 내용을 놓친 것 같습니다. 나는 #define ARRAY_SIZE 80을 가지고 있는데, 이는 나중에 구현할 때 충분하지 않을 수도 있지만,이 기능을 수행하기에 충분해야합니다.

도움을 주시면 감사하겠습니다.

+0

당신은'i' 그 값 아직'는 scanf ("%의 79s", 공정)이 무엇인지 우리에게 얘기를 가지고,'이다 잘못되어'scanf ("% 79s", process) 여야합니다; – ouah

+0

제대로 보이지 않는 약간의 코드가 있습니다. [MCVE] (http://stackoverflow.com/help/mcve)를 게시해야합니다. 그것은 여러분 모두가 코드가 옳지 않은 곳과 곳을 보는 데 도움이 될 것입니다. –

+0

'i = '를 ARRAY_SIZE;로 초기화했습니다. 왜 원래의 버전과 반대되는'scanf ("% 79s"프로세스)를 사용합니까? 나는'process'의 시작 주소에 입력을로드하려고한다고 생각했습니다. 프로그램에서 잘 작동하지만 꽤 길게 만드는 몇 가지 다른 기능이 있기 때문에 MCVE를 함께 사용하겠습니다. – TomJ

답변

2

가변 process&processchar** 입력 가지며 포인터 변수의 포인터가 아니라 할당 된 버퍼에 대한 포인터를 이미 포인터이다.

sizeof(char)은 항상 정의에 따라 1이므로 malloc() 호출에서 불필요합니다. 당신이 scanf()를 사용하는 경우는 이렇게해야한다 :

scanf("%79s", process) ; 

하지만 길이는 하드 코딩 된 i 또는 ARRAY_SIZEfgets()를 사용하는 것이 좋습니다 중 하나와 관련된 문자열에와 있지 않기 때문에,하지만 당신은 길이 인수를 사용 sizeof(ARRAY_LEN)하는 sizeof(int)과 동일합니다. 당신은 단지 ARRAY_LEN을 의미했습니다. 이 경우, 할당이 i + 1fgets() 때문에 삽입하므로 소정 크기 이내 NUL, 않았을 필요 : 또한

fgets(process, ARRAY_SIZE, stdin) ; 

그것을 고정 길이 배열 malloc()를 사용할 필요가 거의; 입력에 맞게 배열을 설정하는 것이 아니라 배열에 맞게 입력을 제한하는 것입니다.그되는 경우는 내가 제안 :

for(i = 0; i < ARRAY_SIZE; i++) 
    printf("process = %c\n", process[i]) ; 

하지만이 인쇄됩니다 : 입력 데이터 문자 단위의 출력을 위해

char process[ARRAY_SIZE] ; 
printf("Enter process name: ") ; 
fgets(process, sizeof(process), stdin) ; 

, 당신은 %c 형식 지정자하지 %s 필요 배열에서 사용하지 않는, unitialised 자, 그래서 가능성 :

for(i = 0; process[i] != '\0'; i++) 
    printf("process = %c\n", process[i]) ; 

또는 process 보낸 문자열을 종료 널로는 s입니다 의미 :

printf("process = %s\n", process) ; 

것은 그래서 궁극적으로 당신이 필요로하는 모든입니다

char process[ARRAY_SIZE] ; 
printf("Enter process name: ") ; 
fgets(process, sizeof(process), stdin) ; 
printf("process = %s\n", process) ; 
+0

아름답습니다. 그 매력처럼 작동합니다. 실제로 데이터를'stdin'에서 배열로 가져 오는 방법에 대한 오해가 있었으며 완벽하게 대답했습니다. 감사합니다. 클 리 포드, 당신은 나를 위해 많은 것을 명확히했습니다. – TomJ

0
#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    char *process; 
    int i = 0;//number of input character; 
    size_t size;//Allocated size 
    int ch; 

    //process = (char *)malloc(sizeof(char) * (i+1));//+1 for '\0' 
    size = 16;//Initial size 
    process = malloc(size);//cast don't need in C 

    printf("Enter process name: ");//fflush(stdout); 
    while((ch = getchar())!=EOF && ch != '\n'){ 
     if(i == size -1){//-1 for NUL('\0') 
      char *temp = realloc(process, size += 16);//expand size 
      if(temp==NULL){ 
       fprintf(stderr, "failed to malloc\n"); 
       free(process); 
       exit(EXIT_FAILURE); 
      } 
      process = temp;//successfully extended update 
     } 
     process[i++] = ch; 
    } 
    process[i] = 0; 
    printf("process = %s\n", process);//type of process[i] is `char` 
    free(process); 
    return 0; 
} 
관련 문제