# Compiler doesn't warn about pinter referencing array past it's lifetime

**URL:** <https://ziggit.dev/t/compiler-doesnt-warn-about-pinter-referencing-array-past-its-lifetime/10162>\
**Category:** Help\
**Tags:** memory-management\
**Created:** [May 17, 2025, 7:30pm UTC](https://ziggit.dev/t/compiler-doesnt-warn-about-pinter-referencing-array-past-its-lifetime/10162 "2025-05-17T19:30:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zaurs9000](https://ziggit.dev/letter_avatar_proxy/v4/letter/z/838e76/32.png) [@Zaurs9000](https://ziggit.dev/u/Zaurs9000)\
**Post date:** [May 17, 2025, 7:30pm UTC](https://ziggit.dev/t/compiler-doesnt-warn-about-pinter-referencing-array-past-its-lifetime/10162/1 "2025-05-17T19:30:54Z")

</div>

I’m a bit confused about this scenario: Shouldn’t the compiler or even the LSP warn about a line like `const fields = fields_array[0..index];` since the lifetime of `fields_array` ends with the function, as shown below?

I don’t have experience with manual memory management, so trying to stay alert.

```zig
const HttpMessage = struct {
    start_line: [] const u8,
    fields: [][] const u8,
    message: ?[] const u8,

    pub fn init(buf: []const u8) HttpMessage {

            var tokenizer = std.mem.tokenizeSequence(u8, buf,"\r\n");
            const start_line = tokenizer.next().?;
            var fields_array: [30][]const u8 = undefined;
            var index: u32 = 0;
            while(tokenizer.next()) |header|: (index += 1) {
                if (header.len == 0) {
                    break;
                }
                fields_array[index] = header[0..];
            }
            const fields = fields_array[0..index];
            var message: ?[] const u8 = undefined;
            if (tokenizer.next()) |text| {
                message = text;
            } else {
                message = null;
            }
            return HttpMessage{
                .start_line = start_line,
                .fields = fields[0..],
                .message = message,
            };
    }
};

```

---

<div class="post-metadata">

**Author:** ![00JCIV00](https://ziggit.dev/user_avatar/ziggit.dev/00jciv00/32/1069_2.png) [@00JCIV00](https://ziggit.dev/u/00JCIV00)\
**Post date:** [May 17, 2025, 7:44pm UTC](https://ziggit.dev/t/compiler-doesnt-warn-about-pinter-referencing-array-past-its-lifetime/10162/2 "2025-05-17T19:44:56Z")

</div>

There’s been some discussion on this recently [here](https://ziggit.dev/t/what-makes-ban-returning-pointer-to-stack-memory-difficult/9380).

I haven’t read through that in a while, but I do believe the core team has some plan to address cases where possible.

---

<div class="post-metadata">

**Author:** ![Cloudef](https://ziggit.dev/user_avatar/ziggit.dev/cloudef/32/1370_2.png) [@Cloudef](https://ziggit.dev/u/Cloudef)\
**Post date:** [May 18, 2025, 4:58am UTC](https://ziggit.dev/t/compiler-doesnt-warn-about-pinter-referencing-array-past-its-lifetime/10162/3 "2025-05-18T04:58:02Z")

</div>

> <https://github.com/ziglang/zig/issues/23528>
>
> I didn't see anywhere this was clearly written up so here it is.
> 
> It's not possi…ble to catch use-after-free of stack memory at compile-time (#5725) because it can be equated to the halting problem. I'll leave that proof as an exercise for the reader.
> 
> So, we catch it at runtime, in safe build modes.
> 
> Step 1, do escape analysis. Only stack locals which have pointers captured which might outlive their scope are subject to these safety checks.
> 
> Step 2, introduce an API for heap-allocating memory, like this:
> 
> \`\`\`zig
> extern fn safe\_alloc(size: usize, alignment: u8) ?\[\*\]u8;
> extern fn safe\_free(ptr: \[\*\]u8, size: usize, alignment: u8, rbp: usize) void;
> \`\`\`
> 
> These would default to using a slimmed down version of \`std.heap.DebugAllocator\` - one that avoids reuse of memory addresses, but does not capture stack traces. Perhaps this would be implemented in compiler\_rt so that it could be optimized and be compiled \*without\* these safety checks, which would otherwise be recursive.
> 
> The subset of stack values which have possibly escaped pointers would then be allocated this way. As an optimization, if there were multiple escaped values in the stack frame, they could be allocated together and freed together.
> 
> The allocation function could fail, so the stack slots would still be reserved for such case. Stack base address is passed to \`safe\_free\` so that it can ignore such fallback pointers.
> 
> Heap-allocating instead of stack-allocating is obviously significantly slower, so that's why it's important for Step 1 to work well, in order to make Step 2 rare.
> 
> So then, when a dangling stack pointer is used, it either segfaults, or its bytes have been memset to the \`0xaa\` pattern, making it very likely to immediately trigger a crash. Even if it does not trigger a crash, however, it is still memory safe in the sense that the memory does not alias any other allocations, making it easier to debug in Debug mode, and avoiding a certain class of bugs in ReleaseSafe mode.
