崩溃或“分段故障";当数据被复制/扫描/读取到未初始化的指针时 [英] Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
问题描述
该问题旨在作为所有性质的常见问题的参考:
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屋!