C 포인터 vs Java 참조형 변수 vs 기타 언어 비교

조회수 5880회

안녕하세요

학교에서 배운 C와 C++을 모두 군대에서 까먹고 현재 인턴 아르바이트와 취미로 Java와 C#을 공부하고 있는 학생입니다.

현재 프로그래머스에서 Java 입문 인강을 복습 겸 처음부터 듣고 있는데, 참조 타입을 공부하던 도중 궁금증이 생겨 질문 드립니다.

Java에서 기본형 변수를 제외한 모든 것이 참조형 변수라고 배웠습니다. 클래스, 배열, 등등...

참조형 변수의 개념이 메모리에 올라가 있는 값, 즉 인스턴스를 참조한다고 이해했습니다.

C의 포인터가 유사한 개념이었던 것으로 어렴풋이 기억을 하는데, 제가 찾아본 결과 Java나 기타 언어에서는 포인터를 쓰지 않는다는 글을 많이 봤습니다.

C의 포인터와 Java의 참조형 변수의 공통점과 차이점에 대해 알고 싶습니다. 추가로, 기타 언어(C++, C#, JavaScript, Python, Ruby, 등등)에서는 어떤 방식들이 쓰이는지 알려주시면 감사하겠습니다.

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    자바에 포인터가 없다라고 하면 오해의 소지가 있습니다.

    정확히는 메모리를 직접 핸들링 할 수 없다 라고 해야 맞습니다.

    예를들어 c/c++는 아래같이 가능합니다.

    //c/c++
    int a = 3;
    int *p = &a;        //a 변수의 메모리 주소 번지
    

    32비트 OS의 경우 p 는 정수값이 아니라 0x12abcdef 같은 4바이트의 크기의 메모리 주소입니다.

    c/c++은 p의 값을 0xaaaaaaaa 같이 임의의 메모리 주소로 바꿔버릴 수도 있습니다.

    개발자가 실수로 저렇게 주소값을 바꿔버리면 오류가 발생할 겁니다.

    그러나 자바는 직접 메모리에 접근이 불가능합니다. 직접적으로 불가능한것이지 new 키워드로 생성한 경우 당연히 내부적으로는 메모리 번지에 접근합니다.

    //java
    int a[] = new int[5];    
    

    a는 메모리 주소라는 생각을 가져야 합니다. 실제 int 5개의 공간은 선형으로(나란히) heap 에 할당되어 있고 그 시작주소가 a에 저장되어 있습니다.

    c와 자바의 큰 차이는 c는 메모리 주소를 마음대로 핸들링이 가능한데 비해 자바는 절대 메모리 주소를 직접 핸들링 할 수 없습니다. 즉 자바의 경우 유연성과 약간의 성능을 희생하는 대신 안전성을 선택한 것입니다.

    즉 c는 메모리 번지를 직접 핸들링을 하므로 segment fault 같은 것이 발생할 소지가 있으나 자바는 절대 segment fault 가 일어날 수 없습니다.

    포인터같은 저수준 기능을 잘 이해하는 좋은 방법은 힘들더라도 어셈블리를 공부해보는 것입니다.(어셈블리를 공부하면 얻는 것이 많습니다.)

    • 좋은 답변 감사합니다. 다른 언어(C#, JavaScript, Python, Perl, Ruby, Swift 등등)에서는 메모리 주소를 어떻게 핸들링 하는지도 알려주실 수 있으신가요? Hommy 2018.1.8 09:10
    • 세부적인 것은 약간식 다를 수 있지만 C#, JavaScript, Python, Perl, Ruby, Swift 언어는 직접 메모리번지를 핸들링 할 수 있는 언어들이 아닙니다. 전부 가비지 컬렉터를 가지고 있는 언어들이구요. 객체의 주소로 참조하는 형태입니다. 객체의 주소를 더 이상 참조하는 것이 없으면 가비지 컬렉터가 객체를 삭제하는 형태이구요. 정영훈 2018.1.8 09:38

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)