首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数据复制/扫描/读取到未初始化指针时崩溃或“分段错误”

将数据复制/扫描/读取到未初始化指针时崩溃或“分段错误”
EN

Stack Overflow用户
提问于 2016-05-31 15:17:37
回答 5查看 12.8K关注 0票数 66

这一问题可作为所有常见的性质问题的参考:

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

例如:

代码语言:javascript
复制
char* ptr;
strcpy(ptr, "hello world"); // crash here!

代码语言:javascript
复制
char* ptr;
scanf("%s", ptr); // crash here!
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-05-31 15:17:37

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

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

代码语言:javascript
复制
{
  int data = 0;
  int* ptr = &data;
  ...
}

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

代码语言:javascript
复制
int* ptr = malloc(sizeof(int));

在初始化指针之前使用指针总是一个错误。它还没有指向有效的内存。

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

代码语言:javascript
复制
/*** examples of incorrect use of pointers ***/

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

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

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

代码语言:javascript
复制
/*** 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");

注意,还可以将指针设置为指向定义良好的“letting”,方法是让指针指向NULL。这使得它成为一个空指针,这是一个指针,保证不会指向任何有效内存。这与完全未初始化指针不同。

代码语言:javascript
复制
int* p1 = NULL; // pointer to nowhere
int* p2;        // uninitialized pointer, pointer to "anywhere", cannot be used yet

但是,如果您试图访问null指针指向的内存,则可能会遇到类似于使用未初始化指针时的问题:崩溃或分段错误。在最好的情况下,您的系统注意到您正在尝试访问地址null,然后抛出一个"null指针异常“。

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

进一步读:

指向无效数据的指针

How to access a local variable from a different function using pointers?

Can a local variable's memory be accessed outside its scope?

分割故障及引起

What is a segmentation fault?

s" but not "char s[]"?

s?

Definitive List of Common Reasons for Segmentation Faults

What is a bus error?

票数 49
EN

Stack Overflow用户

发布于 2017-01-20 11:42:18

  1. 指针只指向内存位置。您创建了一个指针,但尚未绑定到内存位置。strcpy希望您传递两个指向两个字符数组的指针(第一个指针不能是常量),如以下签名: char * strcpy ( char *目的地,const char * source ); 样本使用情况: char* ptr = malloc(32);strcpy(ptr,"hello world"); char str32;strcpy(str,"hello world");
  2. 您可以尝试下面的代码片段来读取字符串,直到到达换行符为止(*还可以添加其他空白字符,如"%[^\t\n]s"(选项卡、换行符)或"%[^ \t\n]s" (空格、选项卡、换行符))。 char *ptr = malloc(32);scanf("%31^\n",ptr); (在现实生活中,不要忘记检查scanf()的返回值!)
票数 4
EN

Stack Overflow用户

发布于 2019-01-19 16:28:51

学习C时经常发生的一种情况是试图使用单引号来表示字符串文字:

代码语言:javascript
复制
char ptr[5];
strcpy(ptr, 'hello'); // crash here!
//            ^     ^   because of ' instead of "

在C中,'h'是单个字符文字,而"h"是包含'h'和空终止符\0 (即2 char数组)的字符串文本。此外,在C中,字符文字的类型是int,也就是说,sizeof('h')等同于sizeof(int),而sizeof(char)1

代码语言:javascript
复制
char h = 'h';
printf("Size: %zu\n", sizeof(h));     // Size: 1
printf("Size: %zu\n", sizeof('h'));   // likely output: Size: 4
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37549594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档