This article compares the use of pointers in Go and C/C++, understanding how Go’s pointer design addresses the safety issues inherent in C/C++ while retaining their advantages. Original text:Pointers Made Painless: How Go Solves C/C++’s Biggest Headache[1]

Few things in the world possess both strength and fragility in the same characteristic. In the realm of programming, if I had to give an example, it would be the pointers in C/C++.
In system programming, the benefits of pointers are undeniable — they enable extremely high execution speed and low-level control.
Developers around the world have been using pointers for 30-40 years, and as everything evolves, should pointers evolve as well?
What if we could retain the functionality of pointers while making them easier to use and reducing the likelihood of errors? This is where Go comes in, designed to simplify modern programming.
Example 1: Automatic Memory Management
Go: No Memory Leaks
In Go, memory management is handled by a garbage collector, eliminating the need for manual allocation or deallocation, thus preventing memory leaks.
package main
import "fmt"
type Person struct {
Name string
Age int
}
func createPerson() *Person {
return &Person{Name: "Alice", Age: 30} // Automatic memory management
}
func main() {
p := createPerson()
fmt.Println(p.Name) // No need to free memory
}
C/C++
In C/C++, memory must be managed manually, and forgetting to free memory can lead to memory leaks.
#include <iostream>
#include <string>
struct Person {
std::string Name;
int Age;
};
Person* createPerson() {
return new Person{"Alice", 30}; // Manual memory allocation
}
int main() {
Person* p = createPerson();
std::cout << p->Name << std::endl;
// Forgetting to delete p? Memory leak!
// delete p;
}
Example 2: Nil Pointer Safety
Go: Nil Pointer Safety
In Go, accessing a nil pointer does not cause the program to crash. Instead, it will return a zero value or panic (if an attempt is made to dereference it).
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var p *Person // p is nil
if p != nil {
fmt.Println(p.Name) // Checking nil is safe
} else {
fmt.Println("p is nil") // Gracefully handling nil pointer
}
}
C/C++
In C/C++, dereferencing a null pointer leads to undefined behavior, typically resulting in a crash (segmentation fault).
#include <iostream>
#include <string>
struct Person {
std::string Name;
int Age;
};
int main() {
Person* p = nullptr; // p is null
std::cout << p->Name << std::endl; // Crash: dereferencing null pointer
}
Example 3: Better Dereferencing Method
Golang
// Go: Accessing struct fields with pointers
type Person struct {
Name string
Age int
}
func main() {
p := &Person{Name: "Alice", Age: 30}
fmt.Println(p.Name) // Even though 'p' is a pointer, no need for '->', just use '.'
}
C/C++
// C++: Accessing struct fields with pointers
struct Person {
std::string Name;
int Age;
};
int main() {
Person* p = new Person{"Alice", 30};
std::cout << p->Name; // 'p' is a pointer, needs '->' to access
delete p; // Don't forget to free memory!
}
Hello, I am Yu Fan, I have worked in R&D at Motorola and am currently working in technology at Mavenir. I have a strong interest in technologies such as communications, networks, backend architecture, cloud-native, DevOps, CICD, blockchain, and AI. I enjoy reading and thinking, and I believe in continuous learning and lifelong growth. I welcome discussions and learning together. To ensure you can see my articles promptly in the future, please follow the WeChat public account “DeepNoMind” and set it as a star. If you could also give a quick three-way support (share, like, and view), it would provide me with more support and motivation to continue writing and grow together with everyone!
References[1]
Pointers Made Painless: How Go Solves C/C++’s Biggest Headache: https://medium.com/@kirubaspace/pointers-made-painless-how-go-solves-c-c-s-biggest-headache-1618e8d14d38
Please open in the WeChat client