指针数组 C++ 的分段错误
Posted
技术标签:
【中文标题】指针数组 C++ 的分段错误【英文标题】:Segmentary fault with pointer array C++ 【发布时间】:2021-04-29 10:57:13 【问题描述】:这段代码出现分段错误:
#include <iostream>
using namespace std;
int* arrayCreate(int length)
int *ew[length];
for (int i=0; i<length; i++)
*(ew[i])=i;
return ew[0];
int main()
int *ptr=arrayCreate(7);
cout << *ptr << endl;
当我试图改变这一行时
int *ew[length];
进入
int *ew = new int[length];
我有错误
谁能解释一下这两个声明的区别,为什么会出现分段错误以及如何解决?
【问题讨论】:
您对指针、地址和值的概念很混乱。你需要一个 C 底漆。 【参考方案1】:在第一个版本中,您在堆栈上分配指针数组并返回该数组的一个元素 - 一旦函数完成,该元素就失效了。访问此返回值意味着未定义的行为。
在第二个版本中,您在堆上创建 int 数组(不是指针)。因此语法错误。
你想要的是
int* arrayCreate(int length)
int* ew = new int[length];
for (int i=0; i<length; i++)
ew[i]=i;
return ew;
或者更好的是,不要使用new[]
,使用std::vector
,它会为你管理内存:
#include <vector>
#include <numeric> //for std::iota
std::vector<int> arrayCreate(int length)
std::vector<int> v (length);
std::iota(v.begin(), v.end(), 0); //you can use your loop as well
return v;
【讨论】:
更不用说int *ew[length];
是一个不符合标准C++的VLA。
我没有得到 ew[i]=i; ew是一个指针数组,也就是int*,怎么才能给整数的指针赋值呢?
@Kas int* ew
不是指针数组。它是指向int
的单个指针。
@Kas 变量的类型永远不能在=
的右边。当您有 int* ew [10]
时,ew
的类型是 10 个指向 int 的指针的数组。当你有int* ew
时,类型是pointer to int。 new[]
在堆上分配一个数组并返回指向该数组第一个元素的指针。【参考方案2】:
int *ew[length];
问题1:数组变量的大小必须是编译时常量。 length
不是编译时间常数。因此,该程序是格式错误的。
如何解决?
如果需要动态大小的数组,则需要动态分配。最简单的解决方案是使用std::vector
。
为什么会出现分段错误
观察:ew
中的指针具有不确定的值。它们不指向任何有效的对象。
*(ew[i])=i;
问题2:您通过存储在数组中的指针间接。由于您通过无效指针进行间接寻址,因此程序的行为是未定义的。
问问自己:int
应该指向什么 ew[i]
对象?
如何解决?
不要读取不确定的值,也不要通过无效指针间接读取。
int *ew = new int[length];
在这里,您创建了一个动态整数数组。整数数组不是指针数组。 ew
是一个指向整数的指针。 ew
不是指向指针的指针。
*(ew[i])=i;
在这里,您通过ew
间接访问i
th 后继兄弟,然后通过该兄弟间接访问。但第一次间接导致int
对象,您不能通过int
间接。
如何解决?
不要尝试通过 int
间接传递。
谁能解释一下这两种声明的区别
int *ew[length]
是一个格式错误且未初始化的指向int
的指针数组。 int* ew
是指向 int
的单个指针,在这种情况下使用 int
动态数组的第一个元素的地址进行初始化。
【讨论】:
【参考方案3】:要在 C++ 中为您的数组获取内存,您应该编写:
int *ew = new int[length];
要返回你应该写的指针:
return ew;
这意味着您返回指向数组开头的指针。应该提到的是a[i]
*(a + i)
。你不能写*(ew[i]) = i;
来分配,但是ew[i] = i;
可以。
还应该说在现代 c++ 中不推荐使用原始指针。
【讨论】:
以上是关于指针数组 C++ 的分段错误的主要内容,如果未能解决你的问题,请参考以下文章