C언어의 메모리 구조, 동적할당 malloc, callloc

프로그램이 실행되려면 메모리 공간이 필요하다.
운영체제는 프로그램을 실행시킬 때 메모리 공간을 할당 해 준다.

메모리 공간 : 스텍 Stack, 힙 heap, 데이터 data 영역

DATA 데이터 영역 - 전역변수, static변수 // 프로그램이 시작될 때 할당되어 종료될 때 까지 유지
heap 힙 영역 - 프로그래머가 할당 // ***메모리 동적 할당에서 활용되는 영역
stack 스텍 영역 - 지역변수, 매개변수 // 함수 호출이 완료되면 할당 영역이 사라진다

배열은 상수로 선언되어야 하는 이유 577p
스텍되 데이터 영역에 할당될 메모리 크기는 컴파일타임(compile-time)에 결정되야하기 때문에
누구나 한번씩 생각 해 보는 배열의 선언인...

int arr[i]
scanf("%d", &i);

이런 형태의 선언은 에러가 발생한다.

malloc 함수 & free 함수 메모리 동적 할당-----------------------581p

malloc
동적으로 메모리를 할당하는 함수--heap영역에 메모리를 할당

#include <stdlib.h>
void* malloc(size_t size)
성공시 할당된 메모리의 첫번째 주소 리턴, 실패 시 NULL포인터 리턴

사용 방법

#include
#include

void function(int);
int main(void)
{
int m=0;
fputs("배열의 크기를 입력하세요: ", stdout);
scanf("%d", &m);
function(m);

return 0;
}

void function(int i)
{
//int array[i]; //ProbArray.c에서의 문제점
int* array = (int*)malloc(sizeof(int)*i);
int j;
if(array==NULL)
{
puts("메모리 할당에 실패!");
exit(1); //비 정상적 종료를 의미함
}
/*동적 할당한 메모리 사용*/
for(j=0;j
array[j]=j+1;
for(j=0;j
printf(""%d", array[j]);
printf("\n");

free(array); // 할당된 메모리 소멸
}


calloc

#include <stdlib.h>
void *calloc(size_t elt_count, size_t elt_size)
성공 시 할당받은 메모리의 포인터(void*형), 실패 시 NULL 리턴


malloc 과 사용방법은 거의 동일하다.

int *arr = (int*)calloc(size,sizeof(int));
==
int *arr = (int*)malloc(size*sizeof(int));

파일 입출력 Random Access

#include <stdio.h>
int fseek(FILE * stream, long offset, int wherefrom)

fseek(stream, 2, SEEK_CUR) // 이런 형식으로 입력

wherefrom의 전달인자
SEEK_SET 이라면 파일의 맨 앞으로 이동한다.
SEEK_CUR 이라면 이동하지 않는다. // SSEK_CUR은 현재 위치를 기준으로 이동한다.
SEEK_END 이라면 파일의 끝으로 이동한다.

long offset 위치의 숫자를 +-숫자로 지정해서 앞뒤로 이동

SEEK_SET(SEEK_END)을 전달하면 현재의 파일 위치 지시자의 위치에 상관없이 파일의 맨 앞(뒤)을 기준으로 fseek함수의 두 번째 인자의 크기만큼 이동한다.

SEEK_CUR

파일 입출력 함수

파일 입 출력 함수들






























  키보드/모니터 선택(키보드/모니터,파일)
문자출력 int purchar(int c) int fputc(int c, FILE* stream)
문자입력 int getchar(void) int fgetc(FILE* stream)
문자열 출력 int puts(const char* s) int fputs(const char* s, FILE* stream)
문자열 입력 char* gets(char* s) char* fgets(char* s,int n, FILE* stream)
형식 지정 출력 int printf(const* format, ...) int fprintf(FILE* stream, cnost char* format,...)
형식 지정 입력 int scanf(const char* format, ...) int fscanf(FILE*stream, const char* format,...)

puts("Dont' worry!"); // puts는 모니터상으로 출력
fputs("dont'w worry!\n", stdout); // stdout 스트림을 활용 모니터에 출력
fputs("dont worry!\n", file); // file 스트림을 활용.. fopen을 통해 개방된 파일에 저장

char buf[30];

fputs("데이터 입력: ", stdout);
fgets(buf, sizeof(buf), stdin); //buf 배열에 stdin을 통해 문자열을 입력 후 ENTER
puts(buf); //buf에 저장된 문자열을 출력

fgets(buf,sizeof(buf), file); // buf배열에 file의 문자열을 buf의 크기 한도 내에서 저장
puts(buf); // buf를 출력

파일 입 출력 함수와 FILE 구조체 변수----------------------------
파일위치 지시자...File Position Indicator
fgetc, fgets등을 여러번 호출하면 이전에 호출했던 위치에서 이어서 호출이 된다.
이러한 일이 가능한 것은 파일을 어디까지 읽었는지 어디까지 섰는지 그 위치를 기억하고 있다는 뜻.

= 파일을 개방하는 경우 이에 대한 FILE 구조체 변수의 포인터가 리턴되고, 그 포인터가 가리키는 구조체 변수 내에는 '파일 위치 지시자'에 해당하는 변수가 존재한다. 이 변수는 파일 내의 위치 정보를 지니고 있으며, 이 변수의 값은 파일에서부터 데이터를 읽거나 쓰는 경우 변경된다.

--------------파일의 끝에 도달한 경우 리턴------------
fgetc --> EOF(-1)을 리턴
fgets --> NULL포인터 (0)
fscanf --> EOF(-1)

----------feof  파일의 끝을 검사하는 함수---------
#include <stdio.h>
int feof(FilE*stream)

~~~~~~~~~~~~~~
file=fopen("Test.txt","rb"); //읽기전용 파일 개방
if(file==NULL){
  printf("file open error!\n");
  return 1;
}

while(1)
{
  ch=fgetc(file);
  if(feof(file)!=0)  //feof함수를 활용해 파일을 끝을 검사하고 break로 종료
    break;
  printf("data : %c \n", ch);
}
//여기서 파일을 종결하면 됨
state=fclose(file);
if(state!=0){
  printf("file close error!\n");
  return 1;
}
return 0;

파일입출력 - 파일의 개방 open 종결 close

fopen함수 - 파일 개방

#include <stdio.h>
FILE* fopen (const char * filename, const char * mode)
성공 시 해당 파일의 파일포인터, 실패시 NULL 포인터 리턴


fclose함수 - 파일 종결

#include <stdio.h>
int fclose (FILE * stream)
종료가 오류 없이 제대로 이뤄지면 0을 리턴


사용 예

#include <stdio.h>
int main(void)
{
  int state;
  FILE*file=fopen("c:\\work\\test.txt", "rt"); //파일 개방
  if(file==NULL){
    printf("file open error\n");
    return 1;
  }
  state=fclose(file);  //파일의 종결
  if(state!=0){
    printf("file close error!\n");
    return 1;
  }
return 0;
}


파일 접근 모드
r - 읽기전용
w - 쓰기전용, 파일이 없으면 새로 생성, 파일이 있으면 기존파일을 지우고 생성
a - 파일의 끝에서 내용추가 전용
r+  -파일을 읽고 쓰기, 파일이 존재하지 않으면 새로운 파일 생성, 파일이 존재하면 데이터를 덮어쓰기
w+ - 파일을 읽고 쓰기, 파일이 존재하지 않으면 새로운 파일 생성, 파일이 존재하면 기존파일을 지우고 생성
a+ - 파일을 읽고 쓰기, 파일이 존재하지 않으면 새로운 파일 생성, 파일이 존재하면 끝에서부터 데이터 추가

데이터 입출력 모드 541p
t - 텍스트 모드
b - 바이너리 모드(2진 모드)

main 함수 인자 전달 int main( int argc, char**argv)

int main( int argc, char*argv[])

tar zxvf game.tar.gz
tar이라는 실행파일에
(1) tar (2) zxvf (3) game.tar.gz
3개다. int argc는 3이 전달된다.
char*argv[3] 세개의 문자열을 꺼내서 쓸 수 있다.... 아마도...

main.exe 파일 실행시에...
main 샘슝 꼬랐다  //3개의 문자열
main 애미콜좆다 //2개의 문자열
main "샘슝 꼬랐다" //2개의 문자열
참고...

if문을 통해 인자의 수를 제대로 입력했을 경우에만 실행되도록...
if (argc != 3)
{

  printf("사용방법이 잘못됐다");

  return 1; //이걸로 종료시켜버린다.
}