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:
- De-allocation: If a pointer is pointing to a memory location of an object, but the object either has been deleted or de-allocated.
- Function Call: If a pointer is pointing to a local variable of a function and the function call gets over.
- 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.
#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.
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.
Top comments (0)