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

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

问题描述

此问题旨在作为所有常见问题的参考:

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.这使它成为一个空指针,它是一个保证不指向任何有效内存的指针.这与让指针完全未初始化不同.


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".

空指针异常bug的解决方法是一样的:使用前必须先设置指针指向有效内存.

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

延伸阅读:

指向无效数据的指针
如何使用指针从不同的函数访问局部变量?
可以在其范围之外访问局部变量的内存吗?

分段错误及原因
什么是分段错误?
为什么写入使用char *s"初始化的字符串时出现分段错误.但不是char s[]"?
char s有什么区别[] 和 char *s?
分段错误常见原因的最终列表
什么是总线错误?

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

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