'동적할당'에 해당되는 글 2건

  1. 2008.02.27 [JAVA] 2차원 배열 동적할당 (2)
  2. 2007.11.30 <C++> 메모리공간 동적할당
。공부 。2008.02.27 23:49
우리는 배열을 이용해서 힙영역에 내가 원하는 크기만큼의 배열을 동적할당할수 있습니다.
왜굳이 동적할당을 해야하나? 그냥 넉넉하게 지정해주면 안되나? 하는 분들도 있겠지만 그렇게 되면 메모리손실이 뜻하지 않게 너무커져버릴수 있기 때문입니다.
고등학교를 예로 든다면 반별로 학생수가 다를수가 있습니다 1반에는 30명 2반에는 35명 이렇게 있을수가 있다는 거죠..
이럴땐 그냥 넉넉하게 배열을 50씩 잡아줄수 있겠지만 우리는 동적할당을 이용해서 배열을 크기를 지정해 보도록하죠.

import java.io.*;

public class Exam_array {
    public static void main(String[] args)throws IOException{
        BufferedReader in  = new BufferedReader(new InputStreamReader(System.in));
        int[][] array = null;        //배열을 만들어 주고 널값을 넣어준다.
       
        System.out.print("배열의 행을 입력 : ");
        int x = Integer.parseInt(in.readLine());
        array = new int[x][];        //new 라는 키워드를 이용해 입력받은 값으로 배열의 행을 동적할당한다.
       
        for(int i=0; i<array.length; i++){
            System.out.print("배열의 "+ i +"번째 열을 입력 : ");
            int y = Integer.parseInt(in.readLine());
            array[i] = new int[y];
        }
       

        for(int i=0; i<array.length; i++){
            for(int j=0; j<array[i].length; j++){
                System.out.println("["+ i +"]["+ j +"]");
            }
        }
    }
}

위와 같이 하면 행과 열을 입력 받을수 있습니다.
new라는 키워드를 이용해 배열의 크기를 지정해주면 쉽게 동적할당이 되는데 여기서 주의해서 볼것이 있습니다
array.length 와 array[].length 가 그것인데..
둘의 차이가 무엇이 길래 array뒤에 '[]' 을 붙여줄때도 있고 안붙일때도 있는지 말이죠
length가 있는걸로 봐서는 배열의 크기를 반환한다는것이죠.  맞습니다 분명 배열의 크기를 배환하는것입니다.
하지만 array앞에 '[]' 가 붙지않는다면 바로 행의 크기를 반환하고 '[]'가 붙는다면 열의 크기 반환한다는것입니다.
사용자 삽입 이미지












위의 이미지는 int array[][] = new int[3][2]; 였을때 메모리 영역에 할당되는 것을 그림으로 표현해 본것입니다. int array라는 것은 스텍영역에 4Byte로 할당되는 것을 볼수 있습니다 만약 char형이였다면 몇바이트가 할당될까요? 2Byte라고요? 아니죠 데이터를 힙영역에 할당하고 있기때문에 변수 array는 레퍼런스 변수가 됩니다 즉 주소를 가르키게되는 포인터가 되는것이죠 그렇기때문에 자료형이 무엇이든간에 new라는 키워드로 만들어진 변수의 크기는 4Byte가 됩니다.
이 array라는 녀석은 힙영역에 있는 int[3]을 가리키게 됩니다 자바에선 1차원 배열만을 가르킬수 있기때문에 바로 앞에 있는 공간 즉 그주소를 가르키게 되는것입니다 그리고 그주소는 또다시 바로 앞에 있는 주소를 가르키게 되는것이죠 배열은 레퍼런스이기 때문에 가르키는 주소값은 4Byte 됩니다. 마지막공간은 실제 자료형의 크기를 갖게 되는데 여기서는 이역시 int형이기 때문에 4Byte를 갖게 되는것입니다. 만약 char형이라면파란색세로줄 부분의 4라는 숫자는 2로 표기를 했을겁니다.
우리는 왜 '[]'를 붙여주고 안붙여 주는지를 알았습니다.
그럼 array.length 는 배열 array[3][2]  의 첫번째 값이 3을 반환하게 되는것이죠
array[].length는 2를 반환하게 되는겁니다.

흠.. 제표현이 맞았는지 모르겠네요.. 틀린점있음 바로 수정 들어가겠습니다. ^^;
신고
Posted by kyoe
。공부 。2007.11.30 23:22
메모리공간을 효율적으로 사용하기 위해 우리는 메모리공간을 동적할당한다.
물론 배열을 이용해도 똑같은 결과를 얻을수 있지만 만약 데이터를 사용자로 부터 입력을 받는다고 했을때 모든사용자가 똑같은 길이의 값이나 내용을 입력하진 않을것이다 이럴때 배열을 이용한다면 우리는 배열의 크기를 얼마로 잡아야할지 정말 난감할것이다 이럴때 메모리공간은을 동적할당한다면 문제는 해결된다 사용자가 입력한 데이터의 길이만큼 메모리공간이 할당되기때문에 메모리공간은 효율적으로 운영이 된다.

- 동적할당 예제 -
class apple{
    char *name;
    char *address;
    int number;
public:
    apple(char *_name,char *_address,int _number);
};

apple::apple(char *_name,char *_address,int _number){
    name=new char[strlen(_name)+1];     //힙영역에 메모리공간 할당, name은 할당된공간의 포인터를 갖는다.
    strcpy(name,_name);      //할당된공간에 데이터 복사
   
    address=new char[strlen(_address)+1];
    strcpy(address,_address);
    number=_number;
}

int main(void){
    apple aa("kyoe","청주 과학대학",2003);   //객체생성
    return 0;
}

위예제 메인함수에서 apple클래스의 객체 aa를 생성하고 있다 aa객체는 스택영역에 메모리가 할당이 된다.
아직 생성자를 호출하지 않았기 때문에 단지 메모리공간만을 할당하고 있을 뿐이다.
apple클래스의 생성자 apple()의  매개변수로 *_name,*_address,_number를 받고 있다 메인함수에서 매개변수로 'kyoe'라는 문자를 넘겨주고 있는데 이때 문자자체를 넘겨주는 것이 아니라 'kyoe'가 스택영역에 할당된 메모리 주소 를 생성자에 넘겨주게 되는것이다.
apple()생성자의 '*_name'이 주소를 넘겨받고 new키워드에 의해 메모리공간을 동적할당하게 된다 이때  char[strlen(_name)+1]; 명령에 의해 입력받은 문자의 길이만큼 동적 할당되게 되는것이다.
strlen()함수는 문자열의 길이를 리턴하게 된다 현재 _name은 문자열의 길이는 4바이트가 들어있으므로 널문자를 제외한 4바이트가 리턴이되고 널문자를 포함하기 위해 +1을 해주는것이다. 이렇게 힙영역에 길이가 5인 캐릭터형배열이 할당되고 new라는 연산자에 의해 name변수에 힙영역의포인터주소를 리턴하게 됨으로써  name은 그 할당된 메모리공간을 가르키게 되는것이다.
이렇게되면 단지 메모리 공간에 사용자가 입력한 길이의 메모리공간만이 할당됐을뿐 아무것도 들어있지 않는 공간이 된다 .
strcpy(name,_name); 명령으로 _name가 가르키는 값을 힙영역에 할당된 메모리공간을 가르키는 name에 1바이트씩 복사를 해줌으로써 데이터는 힙영역메모리공간에 들어가게 되고 동적할당이 완성이되면서 객체가 생성되는것이다.

음... 복잡하게 설명한듯.. ㅡㅡ;;

신고
Posted by kyoe

티스토리 툴바