반응형

메모리 초기화 함수

memset( void * _Dst,

            int _Val,

            size_t _Size );

연속된 메모리 초기화 함수, _Dst 시작되는 메모리 주소를 넣어주고, _Size sizeof(자료형*) * 개수 만큼 _Val 값으로 모두 초기화 해준다, for 대신에 사용할 있다.

 

 

 

메모리 복사 함수

memcpy( void* destination,

            void* source,

            size_t num );

 

memmove( void* destination,

               void* source,

               size_t num );

함수 모두 메모리의 일부분을 복사하여 가리키는 위치에 붙여넣는다, source 가리키는 곳부터 num 바이트 만큼을 destination 가리키는 곳에 복사한다. 또한 source '\0' 종료 문자(null terminating character) 검사하지 않는다. 언제나 정확히 num 바이트 만큼을 복사한다.

 

두함수의 차이는

memcpy 메모리의 내용을 직접 copy 하고, memmove copy 메모리의 내용을 임시 버퍼에 저장한 copy 한다, 그렇기 때문에 memcpy memory overlap 현상이 일어날 있고, memmove 그렇지 않지만

memcpy 비해 속도가 떨어진다

속도는 memcpy 좋고, 안정성은 memmove 좋다 하지만 2019 기준으로 memmove 속도가 memcopy 많이 따라잡아서 memmove 사용을 권장하는편이다

 

오버 플로우 문제를 방지하기 위해 destination source 가리키는 배열의 크기는 반드시 num 바이트 이상이어야 하며, 서로 겹치면 안된다.(만일 메모리 블록이 겹쳐져 있다면  memmove 함수를 이용하는것이 좋다)

반응형

'C' 카테고리의 다른 글

expression(표현식)  (0) 2020.03.12
Local Variable, Global Variable, Static Variable  (0) 2020.02.28
fseek, ftell, 파일 크기 알아내기  (0) 2020.02.25
FileStream Input Output  (0) 2020.02.22
반응형

expression(표현식)

프로그램 언어에서 값을 나타내기 위해서, 변수나 상수, 연산자로 구성된식, 표현식은 항상 결과(반환)값을 갖음

  1. 일차식
  2. 상수
  3. 괄호식
  4. 전위연산자 수식
  5. 후위연산자 수식
  6. 단항식
  7. 이항식
  8. 삼항식
  9. 할당 수식

 

 

1. 일차식

  • 식별자,변수이름(identifier)

    • iNum, fLength, INT_MAX 등등

    • 연산자(operator) 없이 오직하나의 피연산자(operand) 이루어진 가장 기본적인 형태

 

2. 상수(Constants)

    • 5, 3.14, 'A', "HelloWorld" 등등

 

3. 괄호식(Parenthetical Expression)

    • (2*3)+4, (a = 23+b*) 등등

 

4. 전위 연산자 수식

  • 연산자(operator)가 피연산자(operand) 앞에 오는 형태

  • x = ++a;

    1. a = a+ 1; // a 값에 + 1 값을 a 대입한다
    2. x = a // x a 값을 대입한다,
    3. ++a a 1증가한 이후의 값이다, 변수의 참조보다 먼저 연산을 수행

 

5. 후위 연산자 수식

  • 연산자(operator)가 피연산자(operand) 뒤에 오는 형태

  • x = a++;

    1. x = a // x a 값을 대입한다
    2. a = a + 1 // a 값에 +1 값을 a 대입한다.
    3. a++ a 1증가하기 이전의 값이다, 변수의 참조 후에 연산을 수행

※전위연산자, 후위연산자는 오직 변수만 피연산자로 가능

상수나 일반 수식을 피연산자로 사용 불가능

int a = ++10; // 상수에는 불가능

(a+1)--; // 일반 수식 에도 불가능

 

 

6. 단항식(Unary epxression)

  • 피연산자(operand)즉 연산자에 적용되는 항이 한 개 있는 표현식(expression)

  1. 전위, 후위 증감 연산자 : ++a, --a, a++, a--

  2. sizeof

  3. 부호 연산자 : +a, -a

    • 여기서 산술연산자와 부호연산자가 같다고 생각할 있지만, 다르다, 산술연산자는 연산자가 피연산자 사이에 올때만 가능하다, 1+a, 2-a, a*b, a/b, a%b

  4. 형변환(casting) 연산자, (자료형)변수 : (float) iNum

  5. 주소 연산자(&) : &iNum

  6. 역참조 연산자 *  : *ptr_iNum;

 

7. 이항식(Binary expression)

  • 연산자가 피연산자 사이에 있음
  1. 산술연산자 : a + 7 , 3 + 4, b - 11, 5%2
  2. 논리 연산자 : !, &&, ||, &, |, <, >, <=, >=, ^

 

8. 삼항식(Ternary expression)

  • a ? B : C
  • 조건식 A 참이면 B 아니면 C

    • int result = a > 3 ? 1 : 0; // a 3보다 크면 1 result 대입, 아니면 0 result 대입

       

       

 

9. 할당수식(Assignment expression)

  • a = 7

  • 우측의 값을 좌측의 저장장소에 저장 하라는 의미
  • 할당 연산자를 기준으로 좌측은 Lvalue 라고 하고 우측을 Rvalue 라고 한다
  • Lvalue는 또다른 명칭으로 locator value이며 저장 장소를 뜻한다,
  • Rvalue는 evaluated value, value of an expression 즉 수식의 결과 값이다

 

반응형

'C' 카테고리의 다른 글

memset, memcpy, memmove  (0) 2020.03.13
Local Variable, Global Variable, Static Variable  (0) 2020.02.28
fseek, ftell, 파일 크기 알아내기  (0) 2020.02.25
FileStream Input Output  (0) 2020.02.22
반응형

주의_1 while문 안에 switch를 사용할 때 

while문안에 if 문에서 break 하면 그뒤에 코드들은 거치지 않는다, 즉 if문은 원하는 지점에서 while문을 탈출 시킬 수 있다

위와 같이 while 안에 if 문을 써서 조건을 만족하면 break 문을 사용하여 while 문을 탈출 시킬수 있다

 

그런데 조건문중에 switch 문이 존재하고, while문과 switch 문을 아래와 같이 사용하면

while 안에 switch 안에 break 는 while 문을 탈출 시키지 못한다

break 문이 있다 치더라도, while문을 빠져나오지 못한다, 이유는 switch 안에 break문의 용도는

다음 케이스 문을 거치지 않고, switch문을 중단 시키는 용도 뿐이지, while문을 빠져나오진 못한다

 

해결책

빠져나오게 하고 싶다면, switch 문을 가장 마지막에 두고, switch 문의 case 만족할때

while문의 조건을 두고 있는 bool 변수를 false 시키는 것이다, 그러나, while 문안에 if, break 처럼

원하는 부분에서 중단 시킬 없다

 

switch를 가장 마지막에 두고 while 조건을 false로 바꾸면 가능하긴 하다 그러나 if 문처럼 원하는 지점에서 바로 탈출할 수 없다.

 

 

 

또는 return 문을 써서 switch 문도 while 문을 원하는 지점에서 바로 탈출 할 수 있기는 하지만 그와 동시에 전체 함수가 종료 된다.

 

반응형
반응형

EX02 HEAP CORRUPTION DETECTED

동적 할당을 하는 프로그램을 만들던 도중, free() 함수를 실행할때 에러 발생

 

원인:

Google 찾아보니, 할당한 영역을 벗어나서 접근하게 될경우 발생하는 에러 라고

 

 

 

 

/*Decoding        */

FileStreamInit(&fileStream, fileName, "r"); //파일크기에 따른 g_CodeSize 초기화

 

if (g_CodeSize == 0)

{

     printf("\nError, No data in codefile, zero codeSize\n");

     exit(1);

}

 

g_Buffer = (char*)calloc(g_CodeSize, sizeof(char));

fread_s(g_Buffer, g_CodeSize, sizeof(char), g_CodeSize, fileStream);

decode(g_Buffer, g_CodeSize);

 

아래 decode 함수에서  str[i] != '\0' 원인 이었음

i size 만큼만 i++ 해야 되는데, 범위를 넘어서 버린듯

 

 

 

해결:

void decode(char* str,size_t size)

{

     size_t i = 0;

     while( i < size )

     {

            str[i] -= 3;

            i++;

     }

}

 

결론: 파일 안에서 글자 수에 따른 범위를 정할때는 index < size 방식이 제일 안전함

반응형
반응형

EX01_읽기 엑세스 위반

 

 

 

원인 : 배열의 인덱스를 벗어난 주소를 찾아서, 금지된 영역에(kernal 영역) 엑세스 하려고 했기 때문에

 

해결 : 배열이 충분히 사이즈가 크게 만들던지, 배열을 가져오는 함수에서 제한 범위를 벗어나지 않게 해야 한다

반응형
반응형

Local Variable(지역변수)

  • 함수 안에서만 사용, 함수에서 선언되고 초기화되며 삭제됨
  • 다른 파일에서 참조할 일이 없으므로, Linkage 필요 없음
  • Stack Segment 에 저장됨

 

Global Variable(전역 변수)

  • 프로젝트 전체에서 사용, 프로그램이 종료 될때까지 존재함
  • 가급적이면 사용을 권장하지 않음
  • Data Segment에 저장됨
  • 장점 : 간단한 코드를 작성할때는 유용함
  • 단점 : 여러곳에서 초기화 있기때문에, 이도 저도 못하는 상황이 있음, 디버깅이 어려워짐

 

주의

  • 변수 선언과 정의를 따로 분리 하지 않고, 헤더파일에 선언과 동시 초기화를 하게 되면 문제가 발생함, 하나의 전역 변수(constexpr, 상수) 여러 .c 파일에서 사용할 경우, .c 파일 개수 만큼 각기 다른 메모리주소를 갖고있는 전역변수가 생김

 

ex1)static const int 전역 변수를 선언한뒤, 각기 다른 .c 파일에서 참조하도록함

 

3개의 함수에서 같은 이름의 전역변수 주소를 확인 했을때 각각 다른 주소를 보임,

 

 

올바른 방식의 전역변수 선언 정의

헤더파일에 선언만 하고, .c 파일에 선언및 정의를 넣어주면 된다

 

결과

 

Static Local Variable(정적 지역 변수)

  • 선언된 함수에서만 사용, 외부에서 접근 불가능
  • 오직 하나만 존재하는 변수
  • 선언과 동시에 반드시 초기화가 이뤄져야함 그리고 한번만 하게됨
  • 함수내에 static 변수를 선언과 동시 초기화를 하면, 나중에 다시 함수를 호출했을때, 초기화를 반복 하지 않음
  • Data Segment에 저장됨

 

 

Static Global Variable(정적 전역 변수)

  • 파일( *.c )안에서만 사용, 파일 외부에서 접근 불가능
  • 반드시 헤더 파일이 아닌, .c파일에서 선언및 초기화를 해야함
  • 오직 하나만 존재하는 변수
  • Data Segment에 저장됨

 

 

 

반응형

'C' 카테고리의 다른 글

memset, memcpy, memmove  (0) 2020.03.13
expression(표현식)  (0) 2020.03.12
fseek, ftell, 파일 크기 알아내기  (0) 2020.02.25
FileStream Input Output  (0) 2020.02.22
반응형

fseek

(스트림 위치 지정자 이동)

C

 #include <stdio.h>

C++

 #include <cstdio>

 

fseek(FILE* fileStream, long int offset, int origin);

  • origin 인자로 전달된 위치로 부터 offset 만큼 더해진 위치로 위치 지정자(poistion indicator) 이동시킴

 

origin 인자로 들어가는 매크로 상수들이 존재한다, 해당 위치로 이동하고 싶으면

fseek(pFile, 0, SEE_SET); // 시작위치로 이동

처럼 호출하면 된다

 

 

SEEK_SET

파일의 시작

SEEK_CUR

현재 파일 포인터의 위치

SEEK_END

파일의

 

 

주의 : 텍스트 파일에 fseek 함수를 사용할때, offset 인자로 0 아닌 혹은 ftell 함수에 의해 반환된 값을 사용할 때에는 일부 플랫폼에서는 문제가 생겨서, 예상치 못했던 위치로 이동할 있음

 

 

 

 

ftell

(스트림 위치 지정자의 현재 위치를 알려줌)

 

C

 #include <stdio.h>

C++

 #include <cstdio>

 

 long int ftell(FILE* stream);

  • fseek함수와 같이 써서 파일의 크기를 알아내는데 사용한다
  • 이진(binary) 스트림의 경우, 리턴된 값은 파일의 시작 부분에서 현재위치 까지의 바이트 수를 말함
  • 텍스트(txt) 스트림의 경우, 보이지 않는 문자( Line Feed , Carriage Return, ...) 등등도 포함한 바이트 수가 나오게 된다
    • LF : Line Feed, 현재 위치에서 바로 아래로 이동 \n
    • CR : Carriage Return,  커서의 위치를 앞으로 이동 \r

 

fseek + ftell 파일 크기 알아내기

 

ex1)

반응형

'C' 카테고리의 다른 글

memset, memcpy, memmove  (0) 2020.03.13
expression(표현식)  (0) 2020.03.12
Local Variable, Global Variable, Static Variable  (0) 2020.02.28
FileStream Input Output  (0) 2020.02.22

+ Recent posts