在指针迭代中使用 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<int>
,否则请使用std::array<int, 5>
。
让你当前的 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<int> v(4); int* grades = v.data();
: 只要 v 不增加就可以了。如果增加 [...]” -> 潜在的重新分配 -> 指针悬空-> UB【参考方案3】:
您的动态数组已单元化。所以现在它指向一个随机地址。 尝试这样做:
int* grades = new int[4];
// do things
delete [] grades;
所以,操作系统会为你的 4 个整数分配一些空间,而不是一个随机的地方,其中可能还有另一个重要的值。
【讨论】:
以上是关于在指针迭代中使用 for 循环时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章