문제

명령줄 인수를 문자 배열에 전달하는 두 가지 방법을 찾았습니다.

int main (int argc, char **argv)
{
  const char *s1 = argv[0];
  char s2[256];
  strcpy(s2, argv[0]);

  printf("s1: %s\ns2: %s\n\n", s1, s2);
}

AIX 시스템에서 IBM xlc 컴파일러로 컴파일됨

[내 프롬프트]> ./a.out

s1:./a.out

s2:./a.out

어떤 구현(s1 또는 s2)이 올바른가요?s1은 argv[0]의 길이에 제한이 없기 때문에 좋습니다.s2에서는 argv[0] 길이가 256자 미만이어야 합니다.

s1이 어떻게/왜 작동해야 하는지 이해하지 못합니다.나 생각하다 s1의 오른쪽은 컴파일 타임에 필요하지만 생각하다 런타임에 생성됩니다.

도움이 되었습니까?

해결책

S1이 작동하는 이유는 ArgV의 유형 [0]이기 때문입니다. ~이다 포인터. 당신은 단순히 안전한 주소 (실제 값이 아님)를 할당하는 것입니다. 당신은 어떤 종류의 할당이나 캐스트를 수행하지 않습니다.

나는 일반적으로 인수 변수에서만 읽어야하기 때문에 첫 번째 옵션을 선호합니다.

다른 팁

문자열을 변경하고 싶지 않다면 S1이 작동합니다.

문자열을 변경하려면 문자열을 사본을 만들 수 있습니다. 시스템이 지원하는 경우 더 안전한 strnlen () 및 strncpy ()를 사용해야합니다.

컴파일 타임에 S1의 오른쪽은 필요하다고 생각하지만 런타임에 생성된다고 생각합니다.

아니요, 성명서가 발생할 때마다 필요합니다. 예를 들어:

void f() {
   int x = 1;
   ...
}

정수 X는 컴파일 타임이 아닌 함수가 호출 될 때마다 1으로 초기화됩니다.

S2는 버퍼 오버런에 취약한 유쾌한 속성을 가지고 있습니다.

나는 사람들이 ARGV의 가치를 바꾸는 것을 보았다 [0]. 경우에 따라 (일부 OS에서) 변경되는 ARGV [0]는 프로그램을 변경 한대로 PS에 표시 할 수 있습니다.

인수를 변경하지 않고 참조만 하고 싶다면 s1 맞다.

어떤 방식으로든 인수를 수정해야 하는 경우 다음과 같이 인수의 복사본을 만들어야 합니다. s2 예를 들어, 그러나 s2 예를 들어 길이가 복사하려는 버퍼보다 ​​긴지 명시적으로 확인해야 합니다.예를 들어 filename.jpg와 같은 인수를 입력으로 사용하고 filename.gif를 출력으로 저장하는 경우 확장자를 .jpg에서 .gif로 변경하므로 해당 인수의 복사본을 만들어야 합니다.

나는 S1, 특히 n> 0 인 Argv [n]에 대해 S1과 함께 갈 것입니다. S2와 같은 것은 클래식 버퍼 오버플로 공격을 위해 당신을 열어줍니다. 기본적으로, 사용자는 길이가 256자가 넘는 인수를 포맷하고 스택에 정보를 덮어 쓰면 원하는 코드를 실행할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top