거북이처럼 천천히

C언어 잡다한 정보 정리 (1) 본문

C

C언어 잡다한 정보 정리 (1)

유로 청년 2024. 7. 4. 07:55

1. 서로 다른 자료형으로 연산하게 되면 메모리의 크기가 큰 자료형을 따라 결과값이 나오게 된다.

 

문제) 아래와 같이 서로 다른 자료형인 int와 double을 가지고 연산하게 된다면 연산한 결과는 어떤 자료형을 갖게 되는가?

 

int a = 20;
double b = 5.5;

// a / b == 연산 결과 : double형으로 출력

 

정답) int형은 4 byte, double형은 8 byte이고, 8 byte가 4 byte보다 크기 때문에 a / b의 연산 결과는 double 형을 갖는다.

 

 이는 '자동 형 변환'에 의해 발생된다. 자동 형 변환에 의해 int / double을 연산이 이루어지면 int형을 double형으로 자동적으로 형 변환이 발생하여 double / double 형태로 연산을 하여 출력값이 double 형으로 리턴하게 된다.

 

 

2. Shallow copy

와 Deep copy

 문제) 원소들을 다른 배열에 복사할 경우에는 Shallow copy 방법과 Deep copy 방법 중을 이용해야 하는가?

 정답) 배열명은 배열의 첫 번째 원소의 주소값을 가르키는 주소 상수이다. Shallow copy에 사용되는 대입 연산자 경우

           에는 왼쪽에는 l-value가 와야 하는데, 배열명은 데이터 값을 저장할 수 없는 상수(r-value)이기 때문에 배열을 초기
           화하는 과정을 제외하면 배열을 복사하기 위해서 Deep copy 방법을 사용해야 한다.

 

          따라서 대입 연산자를 사용하기 전, 대입하고자 하는 곳이 값을 저장할 수 있는 l-value인지 확인하고 사용해야 한다.

 

 

 

3. Input Buffer를 클리어 하는 방법

 표준 입력 함수를 사용하여 문자 , 문자열을 받는 과정에서 Buffer에 남아 있는 데이터 값들에 의해 의도치 못한 입력이 변수에 저장되는 상황을 자주 접할 수 있기 때문에 문자, 문자ㅁ열을 입력받는 과정에서 주의할 필요가 있다. 

 그래서 이러한 상황을 피하기 위해 Input Buffer를 의도적으로 비우는 작업을 이용할 수 있는데, 이때 사용할 수 있는 방법에는 크게 3개의 방법이 있다.

 

  • getchar() 함수를 이용하여 입력 버퍼 비우기
  • 다음과 같이 while문 과 getchar() 함수를 이용하여 입력 버퍼 비우기
while(getchar() != NULL);

 

  • rewind(stdin) 함수를 이용하여 한 번에 입력 버퍼를 비울 수 있다.



 

4. scanf 함수의 보안 취약성 문제

 scanf 함수는 보안에 취약하다는 문제점에 의해 더 이상 지원을 하지 않으며, 이를 보완한 표준 입력 함수인 scanf_s 함수를 이용할 수 있다. 

 

문제) scanf 함수가 어떤 부분에서 보안 부분에 취약성을 갖고 있는가?

정답) 예를 들어 scanf 함수를 통해 문자열을 입력받고자 하는 상황이다. 이 과정에서 문자열을 입력 받기 위해 길이 10인 
         char형 배열을 이용하여 받고자 했는데, 실제로 scanf 함수를 통해 들어온 문자열의 길이는 문자열의 길이가 9보다 
         큰 문자열이 들어 왔다. 그럼 이 경우에는 메모리에 어떤 형태로 데이터가 저장되는가? 

 

         아래와 같이 입력된 데이터를 모두 저장하기 위해 길이가 10인 배열의 한정적인 메모리 공간을 넘어 다음 메모리 
         영역까지 넘어가 Overwrite (= Overflow) 한 것을 확인 할 수 있다.

 

#include <stdio.h>

int main(void) {
	char data[10] = { 0, };

	printf("문자열을 입력하시오 : ");
	scanf("%s", data, sizeof(data));

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

	return 0;
}

         

data 배열의 메모리 공간 ( 대입하기 전 상태 )
data 배열의 메모리 공간 ( 대입하기 후 상태) , ( 입력 값: HelloWorldHelloWorld )

 

          그래서 만약 overwriter 된 메모리 영역이 보안과 밀접한 데이터일 경우, 데이터가 훼손되면서 보안 시스템에 심각한 

         문제를 발생시킬 수 있기 때문에 더 이상 최신 버전에서는 scanf 함수를 지원하지 않고, 이러한 문제점을 보완한 다른

         표준 입력 함수인 scanf_s 함수를 이용한다. 

 

          scanf_s 함수인 경우에는 3번째 argument 값으로 변수의 메모리 사이즈를 넘겨줌으로서 overwriter 발생을 방지 할 

         수 있으며, 추가적으로 메모리에 overflow 상황이 발생하면 데이터를 메모리에 저장하지 않음으로서 문제를 방지하

         게 된다.

 

         같은 이유로 gets 문자열 표준 입력 함수도 보안에 취약하여 최신 버전에서 더 이상 지원하지 않으며, 이를 보완한

          gets_s 함수를 사용하게 된다.

 

 

 

 

6. Short circuit rule은 무엇인가?

 논리 연산 과정에서 논리 연산자에 따라 추가적인 평가없이 곧바로 결과를 결정할 수 있는 상황"Short circuit이라고 한다. 이를 이해하게 된다면 효율적으로 코드를 작성할 수 있는 동시에 동작 시간을 단축시킬 수 있다.

 

 6.1) OR 연산자 

    → OR 연산자는 둘 중 하나만 True면 1를 출력하기 때문에 앞의 조건이 True면 뒤의 조건은 볼 필요 없이 바로 1을

         출력하게 된다. 

 

 6.2) AND 연산자

    → AND 연산자는 둘 중 하나라도 False면 0을 출력하기 때문에 앞의 조건이 False면 뒤의 조건은 볼 것도 없이 바로

         0을 출력하게 된다.

 

 하지만, 이를 잘못 이해하거나 잘못 사용하게 되면 논리 에러를 발생시킬 수 있기 때문에 이를 주의하고 사용해야 한다.

 

 

 

 

 

'C' 카테고리의 다른 글

공용체  (0) 2024.06.20
구조체의 메모리 공간 크기  (0) 2024.06.20
함수 포인터  (0) 2024.06.19
배열 포인터  (1) 2024.06.19
이중 포인터  (1) 2024.06.19