【问题标题】:Segmentation fault error with 2D arrays C++2D数组C ++的分段错误错误
【发布时间】:2021-06-27 19:05:53
【问题描述】:

我不知道为什么在尝试从创建的数组中设置或获取任何元素时出现分段错误!

这里符合A[0][0] = 1;

我正在使用 g++ 9.3.0。我做错了什么?

#include <iostream>

#define SIMULATIONS 30

using namespace std;

void init_matrixes(int a_rows, int b_cols, int vec_len, double **A, double **B, double **C)
{

    A = new double *[a_rows];
    B = new double *[vec_len];
    C = new double *[a_rows];

    for (int i = 0; i < a_rows; i++)
    {
        A[i] = new double[vec_len];
        C[i] = new double[b_cols];
    }
    for (int i = 0; i < vec_len; i++)
        B[i] = new double[b_cols];

}


int main()
{

    double s;
    int t1, t2, a_rows, b_cols, vec_len;
    
    for (auto v : {50, 100})
    {

        a_rows = v;
        b_cols = v;
        vec_len = v;

        for (int i = 0; i < SIMULATIONS; i++)
        {
            double **A, **B, **C;
            init_matrixes(a_rows, b_cols, vec_len, A, B, C);
            
            A[0][0] = 1; // error here

        }
        std::cout << "size = " << v<< "  time = " << s / SIMULATIONS << endl;
    }

    return 0;
}

【问题讨论】:

  • 参数按值传递,除非您通过引用传递它们。指针也不例外。您的init_matrices 不会从main 初始化ABC
  • 您正在使用函数中的 new 语句分配指针参数的本地副本。您需要分配给变量指向的指针。在main 中,变量A 没有指向分配的内存,因此当您尝试访问它时会出现段错误。
  • 这能回答你的问题吗? stackoverflow.com/questions/373419/…(不是“如何制作二维数组”问题,而是“为什么我的 init_matrices 不能正常工作?”)
  • @ДмитрийПасько - 我不明白您需要“在其他函数中使用这些数组”的评论。只需将它们作为参数传递。我向您展示的示例程序展示了如何创建数组 - 之后,您可以随心所欲地使用它们。

标签: c++ arrays pointers segmentation-fault dynamic-arrays


【解决方案1】:

TL;DR 版本

使用std::vectorthe one described here 之类的矩阵类。由于the magic of RAII,这将消除对特殊分配和释放功能的需求。

出了什么问题?

指针只是另一个变量,但它可以包含另一个对象的位置。与任何其他变量一样,指针将按值传递给函数并默认复制。指向的对象是通过引用传递的(通过指针的方式),而指针本身是通过值传递的。

double **AA 定义为指向double 的指针的指针,该指针是调用者提供的指针的副本。

A = new double *[a_rows];

更新副本,调用者不明智。结果,由于本地A 超出范围,所有分配的内存都在函数结束时泄漏。

那么我该如何解决呢?

通过引用传递指针。

void init_matrixes(int a_rows, 
                   int b_cols, 
                   int vec_len, 
                   double ** & A, 
                   double ** & B, 
                   double ** & C)

ABC,通过引用传递(这次是引用),不再是副本。

A = new double *[a_rows];

更新调用者提供的指针,调用者现在有一个指向有效存储的指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2016-02-20
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    相关资源
    最近更新 更多