指针数组 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 intnew[] 在堆上分配一个数组并返回指向该数组第一个元素的指针。【参考方案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 间接访问ith 后继兄弟,然后通过该兄弟间接访问。但第一次间接导致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++ 的分段错误的主要内容,如果未能解决你的问题,请参考以下文章

将指向数组的指针传递给函数时出现分段错误(C++)

指针数组的分段错误

用指向数组的指针替换衰减的数组导致分段错误

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

Cray 指针和数组的分段错误:我做错了啥?

结构中指向数组的 cudaFree 指针上的 CUDA 分段错误