ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • pointer & memory segment
    컴퓨터 구조 2021. 1. 18. 01:39

    Pointer (feat. char)

     

    char* a = "hello";로 a가 "hello"의 시작점을 가리키게 하고, *a = 'H'를 통해 "hello"를 "Hello"로 바꾸려는 시도를 해보았다. 하지만, 컴파일 결과 우리가 원하던 "Hello"가 제대로 반환되지 않고, 오류가 발생했다.

     

    Code

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	char* a = "hello";
    	*a = 'H';
    	printf("%c", *a);
    }

    위의 코드에서 hello가 변경이 되지 않은 채 프로그램이 종료되는 것이 아니라 왜 오류가 발생하는지가 의문이었다.

     

     

    여기저기 찾아보던 중 microchip-'How do i copy char b[] to the content of char* a variable?'click에서 힌트를 얻었다.

     

     

    원인

     

    air_supply_lab - Memory Management in C/C++: The Heap and the Stack

     

    char* a = "hello"

    위의 코드는 hello라는 string의 첫 번째 주소를 a라는 포인터에 저장하게 된다.

     

    이때, "hello"의 주소는 ROM에 저장되어 있으며, a는 ROM에 존재하는 주소를 가지게 된다.

    메모리는 크게 Code segment, Data segment, Heap segment 그리고 Stack segment로 이루어진다. Code segment는 통상적으로 Read Only Memory인데, "hello"가 ROM(Read Only Memory)에 저장된다는 것이다.

     

    *a = 'H'

    위의 코드를 통해 ROM에 저장되어 있는 "hello"의 값을 바꾸려 했기 때문에 오류가 발생한 것이다.

     

     

    ROM에 존재하는 데이터를 직접 수정할 수는 없기 때문에, 다른 메모리 영역에 같은 내용을 복사한다면 수정할 수 있다.

     

    Heap Segment에 malloc을 활용해서 메모리 공간을 확보했다. memcpy를 이용해 Heap segment에 Code segment에 존재하던 내용을 복사한 후에 Heap segment의 내용을 수정해보자.

     

    + 포인터 a는 Code segment에 존재하는 주소를 가지고 있고, 포인터 b는 Heap segment에 존재하는 주소를 가지고 있다. Code segment, Data segment, Heap segment 그리고 Stack segment 순으로 주소의 값이 점점 작아지는데, 실제로 그러한지 확인해보자.

     

    Code

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
    	char* a = "hello";
    
    	char* b = (char*)malloc(sizeof(char));
    	if (b == NULL) {
    		return 1;
    	}
    
    	printf("%p\n%p\n",a,b);
    	memcpy(b, a, sizeof(a));
    	*b = 'H';
    	printf("%c", *b);
    }

     

    출력 결과를 확인해보면, 실제로 a가 가지는 메모리 주소가 b가 가지는 메모리 주소보다 작음을 확인할 수 있다.

     

    a의 주소가 b의 주소보다 작다.


     

     

    "hello"가 RAM에 저장되는 경우

     

    char a[] = "hello";

    위의 코드를 사용해 a에 "hello"의 정보를 저장하면, "hello"는 RAM에 저장되고, a는 RAM에 저장된 "hello"의 주소를 가지게 된다.

     

    RAM에 저장된 정보는 Read와 Write가 모두 가능하기 때문에, 포인터로 접근해 수정하더라도 문제가 생기지 않는다. 따라서, 아래와 같이 포인터로 문자열을 바로 수정할 수가 있다.

     

    Code

    #include <stdio.h>
    
    int main() {
    	char a[] = "hello";
    	*a = 'H';
    	printf("%s", a);
    }
    //output : Hello

     

     

     

    추가로 공부해 보자.

    char* a = "hello"
    char a[] = "hello";

    위의 두 경우에 왜 "hello"가 저장되는 segment가 다른지에 대해 알아보자.

     

     

     

    reference

    microchip-'How do i copy char b[] to the content of char* a variable?'click

     

    틀린 부분이 있을 수 있습니다.

    '컴퓨터 구조' 카테고리의 다른 글

    Pintos - Virtual Memory  (0) 2021.03.03
    Thread ( + pthread)  (0) 2021.01.23
    B-Tree - 삭제  (0) 2021.01.18
    B-Tree - 삽입  (0) 2021.01.13
    B-Tree - intro  (1) 2021.01.11
Designed by Tistory.