값이 저장된 메모리 주소 얻기, 특정 메모리 주소에 저장된 값 얻기

요즘 같은 개발 환경에서 메모리의 주소를 직접 얻고 해당 메모리에 저장된 값을 읽는 코드를 …? 러스트 프로그래밍 언어에서 …

먼저 어떤 값에 대한 메모리 주소를 얻는 코드는 다음과 같습니다.

fn main() {
    let a = 3224;
    let mut memory_location = (&a as *const i32) as usize;
    
    println!("데이터 저장 메모리 주소 : {}", memory_location);

memory_location이 3224 값이 바인딩된 a의 주소값을 담고 있습니다. 이제 memory_location 값(주소)에 저장된 값을 읽는 코드는 다음과 같습니다.

    unsafe  {
        let v = *(memory_location as *const i32);
        println!("메모리 주소({memory_location})에 저장된 값: {}", v);

        memory_location += 4;
        let v = *(memory_location as *const i32);
        println!("메모리 주소({memory_location})에 저장된 값: {}", v);
    }
}

메모리 주소를 통한 값의 직접적 참조는 매우 매우 위험한 행위이므로 반드시 unsafe 코드임을 명시해야 합니다.

사용자 정의 데이터에 대한 println!의 출력

Rust에서 내가 정의한 데이터를 println!를 이용해 화면에 출력하기 위해서는 반드시 std::fmt::Display 트레이트를 구현해야 합니다. 먼저 다음과 같은 MyStruct라는 데이터를 정의합니다.

struct MyStruct {
    name: String,
    age: u16,
}

fn main() {
    let o = MyStruct {
        name: String::from("Ferris"),
        age: 17,
    };

    println!("{}", o);
}

위의 코드 12번은 에러를 발생하는데, 이는 MyStruct 타입의 o 객체를 콘솔에 출력하기 위해서는 MyStruct에 대해 std::fmt::Display 트레이트를 구현하지 않았기 때문입니다. 정상적으로 작동하기 위해서 위의 코드에 대해 다음처럼 보완하면 됩니다.

use std::fmt;

struct MyStruct { ... }

impl fmt::Display for MyStruct {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "name: {}, age: {}", self.name, self.age)
    }
}

fn main() {
    let ferris = ...

    println!("{}", ferris);
}

보호된 글: Rust

이 콘텐츠는 비밀번호로 보호되어 있습니다. 이 콘텐츠를 보려면 아래에 비밀번호를 입력해주세요:

Rust 개발 환경 구성

VS.Code를 이용하므로 이 사이트에서 Rust 개발환경 구성을 참조하였음.

매우 간단한데 rustup-init.exe를 다운로드 받아 실행시키면 콘솔에서 설치가 진행됨. Rust 컴파일러와 Cargo 실행 파일 등이 최신 버전으로 설치가 되며 Path까지 잡아줌. 나중에 Uninstall은 어찌하라는 것인지… 그냥 폴더와 Path 잡힌 것만 제거하면 되는 것인가? VS.Code에서 확장은 rust-analyzer와 CodeLLDB를 설치해주면 됨. 각각 코드 하일라이팅 등의 기능 제공과 디버깅 기능을 제공함.

Rust 프로젝트를 하나 생성하기 위해서는 콘설에서 다음 코드를 실행하면 됨. 원하는 폴더에서 아래 명령을 실행하면 hello_world라는 폴더가 만들어지고 필요한 파일도 생성됨.

cargo new hello_world

VS.Code를 실행하고 hello_world 폴더를 열면 됨. 그리고 컴파일은 VS.Code의 Shell에서 다음 명령을 실행하면 됨. 아래 명령을 통해 실행 파일이 만들어짐.

cargo build

컴파일과 함께 실행을 동시에 하고 싶다면 다음 명령.

cargo run

물론 VS.Code에서도 그냥 실행이 가능하고 라인 단위 디버깅도 가능함. (단, launch.json 파일 생성이 필요하고 앞서 언급한 CodeLLDB 확장 기능 설치가 필요함.