2011-01-14 6 views
0

내 C 프로그램에서 첫 번째 요소 (요소 0)를 제거하는 동안 char 배열을 다른 배열로 복사하려고합니다.배열을 C로 복사

은 내가 쓴 : 나는 배열 2를 인쇄 할 때

char array1[9]; 
char array2[8]; 
int i, j; 

for(i = 1, j = 0 ; i < 10, j < 9; i++, j++){ 
     array2[j] = array1[i]; 
} 
printf(array2); 

, 그것은 나에게 스택 오버 플로우를 제공합니다.

아이디어가 있으십니까?

+1

당신이 그와 같은 루프를 초기화 할 수 있습니다와 같은 별도의 배열 2를 사용할 필요가 없습니다입니까? 나는 (i = 0; i <8; i ++) {array2 [j] = array1 [j + 1]; } – Shaded

+0

Ummm, C 배열의 첫 번째 인덱스는 0입니다. 마지막 인덱스는 size-1입니다. 따라서 array2 [8]를 할 당하면 array2를 넘치게됩니다. 또한 쉼표 연산자의 조건이 잘못되었습니다. 쉼표 연산자가 첫 번째 값을 버립니다. 대신에 &&를 원한다. – derobert

답변

2

문자열이 널로 끝나지 않으므로 인쇄 할 때 할당 된 8자를 초과하여 문자를 계속 인쇄하지만 그 전에는 스택 공간이 부족합니다. 또한 한 캐릭터를 할당 한 것보다 더 많이 쓰고 있고 조건은 &&과 "결합"해야합니다 - ,은 첫 번째 표현식의 결과를 무시합니다. printf에 문자열 포맷터로 문자열 변수를 사용하지 않는 것이 좋습니다.

char array1[10] = "123456789"; 
char array2[9]; 
int i, j; 
for(i = 1, j = 0 ; i < 10 && j < 9; i++, j++){ 
     array2[j] = array1[i]; 
} 
printf("%s\n", array2); 

또한 i+와 단일 인덱스 변수 i 및 인덱싱 array2를 사용하여 루프를 단순화 할 수 있습니다 :

여기에 코드 fixed입니다. strncpy을 사용하여 루프를 완전히 제거 할 수도 있지만 n이 문자열 + 1의 길이보다 작 으면 널 종료자를 추가하지 않습니다.

+0

C에서 (리터럴이 아닌) 문자열을 출력하고 스택 오버플로가 발생할 때마다 가장 먼저 확인해야 할 점은 문자열이 제대로 끝나야한다는 것입니다. –

0

printf(array2)라고 말하면 null로 끝나는 문자열을 인쇄한다고 생각합니다. array2\0이 없으므로 의 끝을 지나서 printf이 계속 이어져 메모리로 방황하는 것으로 추정되지 않습니다.

0

marcog의 대답을 더 확장하려면 : array1을 9 개의 요소, 0-8로 선언 한 다음 0-9 (10 개의 요소)로 작성합니다. array2와 같은 것.

3

두 가지 문제 : 먼저 문자를 printf으로 인쇄하고 다른 표준 C 문자열 함수와 함께 작업 할 때 문자 배열은 null로 끝나야 함수가 문자열의 끝 위치를 알 수 있습니다. 또한 배열의 끝에서 하나를 쓰고 있습니다.

둘째, printf을 사용하는 경우 거의 입니다. 항상 형식 문자열로 인쇄하려는 문자열을 사용하는 것은 좋지 않습니다.

printf("%s", array2); 

을 대신 사용하십시오. 원래 예제에서와 같이 printf을 사용하고 array2가 사용자의 영향을받을 수 있다면 프로그램은 형식 문자열 취약성에 취약 할 수 있습니다.

+0

+1에 대한 +1. "bad guy"가 문자열을 제공 할 수 있다면 일반 문자열의 printf는 공격 벡터를 제공 할 수 있습니다. 그들은 형식 ​​문자를 문자열에 넣을 수 있고 스택 오버플로를 강제 실행할 수 있으며 자신의 코드가 실행될 가능성이 높습니다. –

+0

또는 어떤 포맷팅도하지 않고 있다면'puts()'를 사용할 수 있습니다. (보통'printf ("% s", xxx)')를 사용하여 제 자신을 발견합니다. –

2

사용 방어 적이기() : 쉽게 그게 전부

memcpy(array2, &array1[1], 8); 

.

0

strcpy() (둘 다 문자열 인 경우) strcpy()은 대상에 대한 포인터와 대상에 대한 포인터를 필요로합니다.원본 배열의 첫 번째 요소를 생략 할 경우 단지 source + 1을 통과 :

char source[] = "ffoo"; 
char dest[] = "barbar"; 

strcpy(dest, source + 1); 

// now dest is "foo" (since the ending \0 is copied too) 

printf("\n%s\n", dest); 
+0

'strncpy'가 아마 더 좋을 것이고, 가능하다면'strlcpy'도 있습니다. – user470379