Categories
Tags
3d ABI Actions algorithms alignment analyze APIT Arc Architecture arm array ascii ash assembly asynchronous attribute base64 bithacks Blogging box c c23 cdylib CHAR_BIT clamp clang clang-format client clippy cmake compiler Computer concat concurrency const_fn constexpr contravariant cos covariant cpp cpu crate CS Customization cybersecurity DataStructure db debugging Demo deserialization discrete dll doc DP drawio dtruss dylib Dynamic emulator example Example FFI ffmpeg flamegraph flat_map fold format FP fsanitize Functional FunctionalProgramming functions futures Fuwari game GATs gcc gccrs generics gitignore glibc GUI hacking hashmap haskell heap hyperfine Imperative inference intel interop invariant iterator join justfile kernel LaTeX leak LFU limits linux lto MachineLearning macOS map Markdown math ML mmap mod mp3 nc nextest OnceLock optimization OS ownership panic parallels perf physics pin postgresql procedure product profiling pub radare2 rayon release reverse RPIT rust sanitizer Science science serialization server shift SIMD sin size SmallProjects so socket std strace String StringView strip strlen struct sum super surrealdb SWAR swisstable synchronous syscall tan test thread time toml tracing traits trap triangulation type uint32_t UnsafeRust utf16 utf8 vector Video vulkan wsl x86_64 xilem zig
453 words
2 minutes
memory_layout_c_rust_vector_array
link
C언어부터 알아보자
- Sure. Assuming
len = 10, this:
uint8_t *my_vec = calloc(len, sizeof(*my_vec));allocates 10 bytes of heap memory, all initialized to zero.
CLI memory layout
Stack
┌─────────────────────────────┐
│ my_vec │
│ │
│ pointer ───────────────────────┐
└─────────────────────────────┘ │
│
▼
Heap
┌─────────┬─────────┬─────────┬─────────┬─────────┐
│ byte 0 │ byte 1 │ byte 2 │ byte 3 │ byte 4 │
│ 0 │ 0 │ 0 │ 0 │ 0 │
├─────────┼─────────┼─────────┼─────────┼─────────┤
│ byte 5 │ byte 6 │ byte 7 │ byte 8 │ byte 9 │
│ 0 │ 0 │ 0 │ 0 │ 0 │
└─────────┴─────────┴─────────┴─────────┴─────────┘
1 byte 1 byte 1 byte 1 byte 1 byteBecause:
sizeof(uint8_t) == 1we get:
len = 10
sizeof(*my_vec) = 1
calloc(10, 1) = 10 bytesWith hypothetical addresses
Suppose calloc() returns address 0x1000:
my_vec
│
│ 0x1000
▼
Heap
Address Value my_vec[i]
───────────────────────────────────
0x1000 0 [0]
0x1001 0 [1]
0x1002 0 [2]
0x1003 0 [3]
0x1004 0 [4]
0x1005 0 [5]
0x1006 0 [6]
0x1007 0 [7]
0x1008 0 [8]
0x1009 0 [9]So:
my_vec[0]means:
*(my_vec + 0) → memory at 0x1000and:
my_vec[5]means:
*(my_vec + 5) → memory at 0x1005Important distinction
my_vec itself is not the array.
Stack Heap
my_vec
┌──────────────┐
│ 0x1000 │──────────────► ┌───┬───┬───┬───┬───┐
└──────────────┘ │ 0 │ 0 │ 0 │ 0 │ 0 │
pointer ├───┼───┼───┼───┼───┤
│ 0 │ 0 │ 0 │ 0 │ 0 │
└───┴───┴───┴───┴───┘
10 bytesThis is one of the key differences from Rust’s Vec<u8>: the C pointer only tells you where the allocation begins. C does not automatically store the len alongside my_vec, which is why your code separately keeps:
size_t len = 10;So conceptually you have:
my_vec ──► [ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ]
└──────────────── 10 bytes ────────────────┘
len = 10The closest C23 equivalent is a dynamically allocated array initialized to 10 zero bytes.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t len = 10;
unsigned char *my_vec = calloc(len, sizeof(*my_vec));
if (my_vec == NULL) {
return EXIT_FAILURE;
}
printf("my vec : [");
for (size_t i = 0; i < len; ++i) {
printf("%u", my_vec[i]);
if (i + 1 < len) {
printf(", ");
}
}
printf("]\n");
free(my_vec);
return EXIT_SUCCESS;
}Rust → C23 mapping
| Rust | C23 |
|---|---|
let my_vec | unsigned char *my_vec |
vec![0_u8; 10] | calloc(10, sizeof(*my_vec)) |
u8 | unsigned char |
my_vec.len() | len |
println! | printf |
automatic Vec cleanup | free(my_vec) |
The important part is:
let my_vec = vec![0_u8; 10];which creates a Vec<u8> containing:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]In C23:
size_t len = 10;
unsigned char *my_vec = calloc(len, sizeof(*my_vec));calloc() is particularly appropriate here because it allocates memory and initializes all bytes to zero.
If you want the C version to be closer to Rust’s Vec abstraction (pointer + length + capacity), I can also show a C23 struct Vec implementation.
memory_layout_c_rust_vector_array
https://younghakim7.github.io/blog/posts/memory_layout_c_rust_vector_array/