崩溃或“分段故障";当数据被复制/扫描/读取到未初始化的指针时 [英] Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer

查看:69
本文介绍了崩溃或“分段故障";当数据被复制/扫描/读取到未初始化的指针时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该问题旨在作为所有性质的常见问题的参考:

This question is meant to be used as reference for all frequently asked questions of the nature:

当我将数据复制/扫描到未初始化的指针指向的地址时,为什么会出现神秘的崩溃或分段错误"?

Why do I get a mysterious crash or "segmentation fault" when I copy/scan data to the address where an uninitialised pointer points to?

例如:

char* ptr;
strcpy(ptr, "hello world"); // crash here!

char* ptr;
scanf("%s", ptr); // crash here!

推荐答案

指针是一种特殊的变量类型,它只能包含另一个变量的地址.它不能包含任何数据.您不能将数据复制/存储到指针中"-这没有任何意义.您只能设置一个指针指向其他地方分配的数据.

A pointer is a special type of variable, which can only contain an address of another variable. It cannot contain any data. You cannot "copy/store data into a pointer" - that doesn't make any sense. You can only set a pointer to point at data allocated elsewhere.

这意味着,为了使指针有意义,它必须始终指向有效的内存位置.例如,它可以指向在堆栈上分配的内存:

This means that in order for a pointer to be meaningful, it must always point at a valid memory location. For example it could point at memory allocated on the stack:

{
  int data = 0;
  int* ptr = &data;
  ...
}

或在堆上动态分配的内存:

Or memory allocated dynamically on the heap:

int* ptr = malloc(sizeof(int));

在初始化指针之前使用指针始终是一个错误.它尚未指向有效内存.

It is always a bug to use a pointer before it has been initialized. It does not yet point at valid memory.

这些示例都可能导致程序崩溃或其他类型的意外行为,例如分段错误":

These examples could all lead to program crashes or other kinds of unexpected behavior, such as "segmentation faults":

/*** examples of incorrect use of pointers ***/

// 1.
int* bad;
*bad = 42;

// 2.
char* bad;
strcpy(bad, "hello");

相反,必须确保指针指向(足够)已分配的内存:

Instead, you must ensure that the pointer points at (enough) allocated memory:

/*** examples of correct use of pointers ***/

// 1.
int var;
int* good = &var;
*good = 42;

// 2.
char* good = malloc(5 + 1); // allocates memory for 5 characters *and*  the null terminator
strcpy(good, "hello");


请注意,您还可以通过将指针指向NULL来将其设置为指向明确定义的无处".这使它成为 null指针,这是一个保证不指向任何有效内存的指针.这与使指针完全未初始化不同.


Note that you can also set a pointer to point at a well-defined "nowhere", by letting it point to NULL. This makes it a null pointer, which is a pointer that is guaranteed not to point at any valid memory. This is different from leaving the pointer completely uninitialized.

int* p1 = NULL; // pointer to nowhere
int* p2;        // uninitialized pointer, pointer to "anywhere", cannot be used yet

但是,如果您尝试访问空指针所指向的内存,则会遇到与使用未初始化的指针类似的问题:崩溃或分段错误.在最佳情况下,您的系统会注意到您尝试访问的地址为null,然后引发空指针异常".

Yet, should you attempt to access the memory pointed at by a null pointer, you can get similar problems as when using an uninitialized pointer: crashes or segmentation faults. In the best case, your system notices that you are trying to access the address null and then throws a "null pointer exception".

解决空指针异常错误的方法是相同的:在使用指针之前,必须将指针设置为指向有效内存.

The solution for null pointer exception bugs is the same: you must set the pointer to point at valid memory before using it.

进一步阅读:

指向无效数据的指针
如何使用指针从其他函数访问局部变量?
能否在其范围之外访问局部变量的内存? /a>

Pointers pointing at invalid data
How to access a local variable from a different function using pointers?
Can a local variable's memory be accessed outside its scope?

分段错误和原因
什么是细分错误?
为什么要做当写入以"char * s"初始化的字符串时,出现分段错误.而不是"char s []"?
char s和有什么区别[ ]和char * s?
分段错误的常见原因的明确列表
什么是总线错误?

Segmentation fault and causes
What is a segmentation fault?
Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"?
What is the difference between char s[] and char *s?
Definitive List of Common Reasons for Segmentation Faults
What is a bus error?

这篇关于崩溃或“分段故障";当数据被复制/扫描/读取到未初始化的指针时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆