在这篇文章中,我将告诉您有关如何处理悬空指针并了解C和GO之间的行为差异。
悬挂的指针
悬空点是指指向适当类型的有效对象的指针。它没有发生在现代编程语言中,例如GO,Rust等,但通常发生在三种情况下:
- 脱位:如果指针指向对象的内存位置,但是对象已被删除或取消分配。
- 函数调用:如果指针指向函数的局部变量,并且函数调用已经结束。
- 变量不在范围:如果指针指向一个超出范围的变量。
这些方案的指针被称为悬空指针。
悬挂的指针可能导致程序中的不确定行为,包括程序崩溃,数据损坏或内存泄漏。为了避免这种情况,我们应始终将指针释放后将指针设置为无效,并避免使用指向其功能范围之外的本地变量的指针。
垃圾收集器
go具有垃圾收集器,并且所有指代对象的变量均已删除,该对象将被系统自动删除。但是,C没有垃圾收集器,这意味着程序员必须自己处理分配的对象。如果他们使用malloc
动态分配内存,则必须照顾记忆的范围和生活期,直到记忆有效为止。
C代码
根据以下代码,new_rect
函数的变量r
预计将在函数之外使用。
#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)
当函数调用结束时,删除了new_rect
函数中存在的变量r
。事实证明,该功能会重新调整一个已经无效的地址。指针rp
指向无效的本地地址,并发生悬空指针错误。
去代码
但是,在以下GO代码中,主要函数中的变量rp
指向NewRect
函数中定义的变量r
的内存地址,尚未删除。因此,悬挂的指针错误不会发生。
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)
那就是所有。