Dangling Pointer between C and Go
Tags: c, go, pointer, danglingpointer
Published: 2023-05-22 04:10:00

---
title: Dangling Pointer between C and Go
published: true
description: Understanding and Handling Dangling Pointer
tags: C, Go, Pointer, DanglingPointer
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
published_at: 2023-05-22 13:10 +0900
---

In this post, I'm going to tell you about how to handle Dangling Pointer and understand the difference of behavior between C and Go.

# Dangling Pointer

Dangling point is a pointer that doesn’t point to a valid object of the appropriate type. It doesn’t happen in modern programming language such as Go, Rust, etc but it usually happens in three scenarios:

1. De-allocation: If a pointer is pointing to a memory location of an object, but the object either has been deleted or de-allocated.
2. Function Call: If a pointer is pointing to a local variable of a function and the function call gets over. 
3. Variable goes out of scope: If a pointer is pointing to a variable that has gone out of scope.

The pointer of these scenarios is known as a dangling pointer.

Dangling pointers can lead to undefined behavior in a program, including program crashes, data corruption, or memory leaks. To avoid this, we should always set pointers to null after they are freed, and avoid using pointers that point to local variables outside the scope of their function.

## Garbage Collector

Go has the Garbage Collector, and all variables that refer to an object are deleted, the object will be automatically deleted by system. However, C doesn’t have the Garbage Collector, which means programmers must handle allocated objects by themselves. If they use `malloc` to allocate memory dynamically, they have to take care of the memory’s scope and living period until the memory is valid.

## C code

In terms of the following code, the variable `r` of the `new_rect` function is expected to be used outside the function.

```c
#include <stdio.h>

// rect represents the coordinate of rectangle.
struct rect {
    float x;
    float y;
};

// new_rect returns a reference of a variable of rect.
struct rect *new_rect(float x, float y) {
    struct rect r = {
        .x =  x,
        .y =  y,
    };
    return &r;
}

int main(int argc, char* argv[]) {
    struct rect *rp = new_rect(2.0, 3.0);
    printf("address = %p\\n", rp);
    printf(" (x, y) = (%f, %f)\\n", rp->x, rp->y);
    return 0;
}
// Output:
// address = 0x16d1c3140
//  (x, y) = (3021218960012547179075862528.00, 0.00)
```

The variable `r` that exists in the `new_rect` function is deleted when the function call ends. It turns out, the function retuns an address that has already been invalid. The pointer `rp` points to the invalid local address and the dangling pointer error occurs.

## Go code

However, in the following Go code, the variable `rp` in the main function points to a memory address of the variable `r` that is defined in the `NewRect` function and has NOT been deleted. So, dangling pointer error doesn’t occur.

```go
package main

import "fmt"

// Rect represents the coordinate of rectangle.
type Rect struct {
	X float32
	Y float32
}

// NewRect returns a reference of a variable of Rect.
func NewRect(x, y float32) *Rect {
	r := Rect{
		X: x,
		Y: y,
	}
	return &r
}

func main() {
	rp := NewRect(2.0, 3.0)
	fmt.Printf("address = %p\\n", rp)
	fmt.Printf(" (x, y) = (%f, %f)\\n", rp.X, rp.Y)
}
// Output:
// address = 0x1400011c008
//  (x, y) = (1.20, 3.40)
```

That’s all there is.