在指针迭代中使用 for 循环时出现分段错误

Posted

技术标签:

【中文标题】在指针迭代中使用 for 循环时出现分段错误【英文标题】:Segmentation fault while using for loop in pointer iteration 【发布时间】:2018-07-17 08:30:45 【问题描述】:

这是我编写的一小段代码,用于测试我对指针的了解:

int *grades;
*(grades+0) = 100;
*(grades+1) = 87;
*(grades+2) = 99;
*(grades+3) = 92;

cout<<*(grades+0)<<endl;
cout<<*(grades+1)<<endl;
cout<<*(grades+2)<<endl;
cout<<*(grades+3)<<endl;

我知道这样分配指针的缺陷。然而,上面的代码 sn-p 正确地打印出每个等级的值。问题是如果我使用 for 循环来自动显示指针的内容。

int *grades;
*(grades+0) = 100;
*(grades+1) = 87;
*(grades+2) = 99;
*(grades+3) = 92;

for(int i=0;i<4;++i)cout<<*(grades+i)<<endl;

为什么添加 for 循环会导致分段错误。我知道分段错误的原因,但是两个sn-ps的代码不是基本相同吗?我使用https://www.onlinegdb.com/ 编写代码。

【问题讨论】:

您的代码只是一个指针,您需要为其分配一个有效地址。现在它指向一些垃圾值 你有一个指针,但是 它指向哪里? 未初始化的局部变量(甚至是指针)将有一个 indeterminate(并且看似随机)的值.在没有初始化的情况下以任何方式使用它们(当然除了初始化它们)会导致undefined behavior。如果你有 UB(未定义行为),那么任何关于行为的讨论都是没有意义的。 另一方面,对于 any 指针或数组p 和索引i,表达式p[i] 恰好 等于@ 987654328@。我建议您始终使用前一种语法 (p[i]),因为它通常更易于阅读和理解。也少写了。 “以 any 方式使用它们是 UB”实际上是不正确的 - 您可以获取地址并将其以指针的形式传递给函数(然后可以分配一些东西)... 取消引用未初始化指针的任何用法都是UB。 我很清楚我的指针没有指向任何有效地址这一事实。我只是在测试编译器的行为。 【参考方案1】:

两种情况(有或没有for 循环)都会遭受相同的undefined behavior 的影响,而 UB 的本质是任何事情都可能发生。这就是为什么您的两个“基本相同”的 sn-ps 在行为上有所不同。

【讨论】:

【参考方案2】:

您的代码表现出未定义的行为。 grades 指向无效内存,因为它未初始化。尝试通过指针读取或写入会导致 UB。它可能看起来有效,但这只是 UB 的一种可能的副作用。

如果您需要动态数组,请使用std::vector&lt;int&gt;,否则请使用std::array&lt;int, 5&gt;

让你当前的 sn-p 工作:

std::array<int, 4> a;
int* grades = a.data();
*(grades+0) = 100;
*(grades+1) = 87;
*(grades+2) = 99;
*(grades+3) = 92;

【讨论】:

我会为向量添加一个警告:“std::vector&lt;int&gt; v(4); int* grades = v.data();: 只要 v 不增加就可以了。如果增加 [...]” -> 潜在的重新分配 -> 指针悬空-> UB【参考方案3】:

您的动态数组已单元化。所以现在它指向一个随机地址。 尝试这样做:

int* grades = new int[4];
// do things
delete [] grades;

所以,操作系统会为你的 4 个整数分配一些空间,而不是一个随机的地方,其中可能还有另一个重要的值。

【讨论】:

以上是关于在指针迭代中使用 for 循环时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

返回指针时出现分段错误[重复]

打印指针时出现分段错误

为啥在访问二级指针时出现分段错误错误? C语言

为啥在尝试使用指针访问结构时出现此分段错误?

删除时出现分段错误

添加指向数组的指针时出现分段错误