운영체제가 파일 또는 하드웨어와 통신을 하기 위해 부여하는 숫자
파일 디스크립터 0
, 1
, 2
숫자순으로 부여됩니다.
0
, 1
, 2
는 파일 디스크립터 테이블에 미리 저장되어 기본적으로 사용중이기에 3
부터 파일 디스크립터를 부여합니다.
0 : 표준입력 STDIN / 1 : 표준출력 STDOUT / 2 : 표준에러 STDERR
open() 함수는 파일을 열고 파일 디스크립터 값을 반환 (실패시 -1 리턴) 그 값을 이용하여 이후에도 계속해서 열었던 파일에 접근 가능합니다.
리눅스의 모든것은 파일로 이루어져 있습니다.
즉 리눅스 기반 운영체제는 fd로 리눅스의 모든 파일들을 관리하고 따라서 프로그램을 실행시키기 위해서는 가장 먼저 파일을 열어야 합니다.
static 변수
는 Global 변수 (전역 변수)
, Local 변수 (지역 변수)
어느 것으로 이용이 가능합니다.
전역이든 지역이든 static 변수
는 데이터 영역
에 위치합니다다.
변수를 선언할 때 static키워드를 붙여 선언한다. static int num
일반 지역 변수가 할당되는 stack 스택 영역
이 아니라 data 데이터 영역
에 저장되어 프로그램이 종료될 때까지 남아있는 변수
함수를 벗어나도 해당 변수는 사라지지 않고 계속 유지를 하지만
함수 내부에서 선언되었다면 다른 함수에서는 이 값을 참조할 수 없다.
또한 함수의 시작이 아닌 프로그램의 시작 시 할당이 되며, 프로그램이 종료될 때 해제된다.
구조체를 static으로 선언한 경우 그 안의 멤버변수들이 0
으로 초기화된다. (지역 변수는 초기화하지 않으면 쓰레기값으로 초기화된다.)
정적 변수
는 초기값을 지정하지 않으면0
으로 알아서 초기화된다.
get_next_line에서는 다음 line을 읽을 시작 주소를 계속 저장할 수 있도록 백업 버퍼를 만들어 static 변수
로 선언해야 한다.
전역으로 선언된 static 변수
는외부 정적 변수
라고도 불리며, 별도의 초기화 구문이 없어도 0
으로 초기화됩니다.
BSS 영역
에 위치하여 0
으로 초기화된다. 초기화 구문 존재 시에는 Data 영역
에 위치합니다.
BBS
는 block started bu symbol의 약어로 초기화 되지 않은 전역 데이터를 위한 영역입니다.
특정 함수나 클래스 내부에 선언된 지역 변수
는 내부 정적 변수
라고도 불리며, 외부 정적 변수
와 마찬가지로 별도의 초기화 구문이 없어도 0
으로 초기화 된다. 또한 내부 정적 변수
의 경우에도 프로세스의 메모리가 할당되는 프로그램의 시작 시점에 이뤄지기 때문에 함수 실행 등으로 인한 선언문에서의 실행으로는 초기화가 이뤄지지 않고 무시된다.
초기화 시점이 프로그램의 시작이라서 함수 실행 시 초기화 구문에서 초기화가 안 된다고 했는데, 이렇게 되어도 문제가 없는 이유는 static
변수는 함수 혹은 클래스에 대해서 내부 정적 변수
로 이용되는 경우에 각 함수 별 혹은 클래스 별로 공유되는 일종의 공유 변수로 이용되기 때문이다.
#include <stdio.h>
void increase_num(void)
{
static int num = 4;
printf("%d\n", num);
num++;
}
int main(void)
{
increase_num();
increase_num();
increase_num();
return (0);
}
위의 경우 static int num
이라는 내부 정적 변수
의 초기화는 프로그램의 시작에 이뤄지며 초기 값은 4
가 됩니다.
이 때 static int num
은 increase_num
이라는 함수의 지역 변수
처럼 보여 Stack
에 위치할 것 같지만, 실제로는 (이 경우에는 초기화 구문이 존재하므로 BSS 영역
이 아닌) Data 영역
에 위치하고 있습니다.
위에서 언급했던 초기화 구문이 동작하지 않는다는 얘기는 increase_num
함수 내의 초기화 구문인 static int num = 4
가 매 함수 실행마다 이뤄지지 않습니다.
또한 내부 정적 변수
는 특정 함수 혹은 클래스 간 공유되어 사용된다고 했기 때문에 위 함수의 실행 결과는 4, 5, 6이 출력됩니다.
포인터가 여전히 해제된 메모리 영역을 가리키고 있다면,
이러한 포인터를 ‘댕글링 포인터(Dangling Pointer)’라고 합니다.
댕글링 포인터가 가리키는 메모리는 더는 유효하지 않아 허상포인터 라고도 불립니다.
즉 이미 해제된 메모리를 가르키는 포인터
입니다.