반응형

python List 메모리에 대해 알아 보겠습니다.

list_a = [1,2,3,4]
list_b = list_a

print("list_a :", list_a)
print("list_b :", list_b)

print("list_a 메모리 :", id(list_a))
print("list_b 메모리 :", id(list_b))

"""
결과
list_a : [1, 2, 3, 4]
list_b : [1, 2, 3, 4]
list_a 메모리 : 1305532916296
list_b 메모리 : 1305532916296
"""

 

list_a의 리스트를 list_b에 대입연산자( = )를 사용하게 되면,

 

list_b에 값이 저장되는 것이 아니라, list_a의 메모리 주소를 저장하게 되어 list_a와 list_b가 서로 메모리 주소를

공유합니다. 

 

만약, list_a에 변수를 추가하게 되면 어떻게 될까요?

list_a = [1,2,3,4]
list_b = list_a

#list_a에 5를 추가
list_a.append(5)

print("list_a :", list_a)
print("list_b :", list_b)

print("list_a 메모리 :", id(list_a))
print("list_b 메모리 :", id(list_b))

"""
결과
list_a : [1, 2, 3, 4, 5]
list_b : [1, 2, 3, 4, 5]
list_a 메모리 : 1866016776776
list_b 메모리 : 1866016776776
"""

결과는 list_a에 5가 추가된다면, list_b에도 5가 추가됩니다.

 

사실상 List명만 다를 뿐, 메모리를 서로 공유하기 때문에 같은 List로 볼 수 있습니다. 

 

그렇다면, list_a와 list_b가 서로 다른 주소를 가지게 하려면 어떻게 해야할까요?

 

list_a = [1,2,3,4]
# .copy를 사용하여 변수 저장
list_b = list_a.copy()

#list_a에 5를 추가
list_a.append(5)

print("list_a :", list_a)
print("list_b :", list_b)

print("list_a 메모리 :", id(list_a))
print("list_b 메모리 :", id(list_b))

"""
결과
list_a : [1, 2, 3, 4, 5]
list_b : [1, 2, 3, 4]
list_a 메모리 : 2337630282312
list_b 메모리 : 2337630282376
"""

copy를 사용하면 메모리의 주소가 아닌, List안의 값들이 저장됩니다.

 

list_a와 list_b의 메모리 주소가 다름을 알 수 있습니다. 

 

서로 메모리의 주소가 다르기 때문에 서로 다른 변수가 됩니다.

728x90
반응형
반응형

3_1.cpp
0.00MB

 

안녕하세요 2차원 배열 동적할당하기 3편입니다. 

 

2편에서는 1차 배열을 2차 배열처럼 표현하였는데 단점으로 배열 사용할 때 인덱스가 복잡하여 사용하기 어려웠습니다.

 

이제는 1편의 2차 배열을 조금 정리하여 이쁘게 표현해보도록 하겠습니다. 

 

 

int** mat;
mat = (int**)malloc(sizeof(int*) * column);

mat[0] = (int*)malloc(sizeof(int) * row *column);


for (int i = 1; i < column; i++) {
     mat[i] = mat[i - 1] + row;
      }

 

이제 포인터 한 번 찍어보도록 하겠습니다.

이렇게 표현하면 그냥 배열처럼 사용할 수 있습니다. 

 

for (int i = 0; i < column; i++)
{
     for (int j = 0; j < row; j++) {
          printf("%d ", &mat[i][j]);
          }
printf("\n");
}

 

 

3 x 3 행렬

5 x 5 행렬도 찍어보겠습니다. 

 

5 x 5 행렬

메모리를 찍어보니 끊어지지 않고 4바이트(sizeof(int))만큼 증가하는걸 볼 수 있습니다. 

 

메모리를 사용했으니 이제 제자리에 돌려놔야겠죠?? 메모리 할당은 조금 복잡하나 해제는 아주 간단합니다.

 

free(mat[0]);

free(mat);

 

 

속도도 1편보다 빠릅니다. (사람 눈에는 차이가 없습니다. 워낙 빨라서...)

 

저는 전공이 하드웨어나 영상처리 쪽이 아니기 때문에 C를 많이 사용하지 않습니다. 당연히 요즘은 파이썬...

 

1학년 때 처음 배운게 C언어였고, 이제 4학년부터는 AVR을 공부하고 캡스톤을 준비해야 하니, 

 

예전에 제가 배웠던 혹은 중요하게 생각하는 부분, 글쓰기를 계속해 나가도록 하겠습니다.

 

728x90
반응형
반응형

예제2.cpp
0.00MB

안녕하세요. 2차원 배열 동적할당하기 두 번째글입니다.

 

1편에서 처럼 2차원 배열을 표현하게 되면 column끼리는 바이트가 순차적입니다.

 

하지만 row끼리는 다른 메모리 공간에서 할당받게 됩니다. 

 

메모리 공간이 순차적이지 않기 때문에 배열에 접근할 때마다 불필요한 동작이 생기게 됩니다. 

 

메모리 공간을 활용하기 위해 다른 방법을 사용하도록 하겠습니다.

 

그림과 같이 일차원 배열을 마치 이차원 배열처럼 표현할 수 있습니다.

일차원 배열로 이차배열만들기

 

장점 : 메모리가 1편처럼 끊어지지 않습니다.

단점 : 1. 배열을 사용할 때 인덱스가 복잡하다는 것입니다. 

      

 

int* mat;       

mat = (int*)malloc(sizeof(int) * column * row);      // 배열의 크기만큼 메모리 할당

 

    for (int i = 0; i < column; i++)

    {

        for (int j = 0; j < row; j++)

        {

            mat[(column * i) + j] = (i * column) + j;      //(i열 ...) + j행

        }

    }

 

메모리를 한 번 할당했으니 메모리 해제도 한 번만 해줍니다.

free(mat);

 

그렇다면 이제 주소를 한 번 찍어보도록 하겠습니다.

3x3배열
5x5배열

728x90
반응형
반응형

1_1.cpp
0.00MB

c언어에서 2차원배열을 만드는 방법은 이와 같습니다. 

arr[3][3] = {0, };

그러면 3X3 2차원 배열이 생성됩니다.

하지만 가로의 크기와 세로의 크기를 컴파일 이전 시간에 미리 정해줘야 합니다.

즉, 가로 안에 상수가 들어가야합니다. 

만약 실행 도중에 사용자가 원하는 크기만큼의 배열을 만들고 싶으면 어떻게 해야할까요?

2차행렬 동적할당

아마 가장 보편적으로 알려져 있는 방법입니다.

 

scanf("%d", column);

scanf("%d", row);

 

int **arr;
arr = (int**) malloc ( sizeof(int*) * column);
for(int i=0; i<column; i++){
    arr[i] = (int*) malloc ( sizeof(int) * row );
}

 

하지만 문제점이 하나 있습니다.

 

만약 주소를 찍으면 어떻게 될까요?

for(int i=0; i<column; i++){

     for(int j=0; row; j++){

          printf("%d  ", &arr[i][j]);  

      }

      printf("\n");

}

 

 

행으로는 포인터가 4바이트로 연결 되지만, 다음 열로 새로운 시작주소를  받습니다.

 arr[0][], arr[1][], arr[2][]의 값에 접근할 때마다 시작주소가 바뀌어 불필요한 동작을 일으킵니다. 

이제 다음 동적할당 예제로는 하나의 시작주소로 시작해 순차적으로 카운트되도록 만들어 보겠습니다.  

 

메모리 공간을 사용했으면 이제 해제해줍니다.

for (i = 0; i < row; i++) {

     free(arr[i]);

     }

free(arr);

728x90
반응형

+ Recent posts