简体   繁体   English

打印多维数组内容时出现分段错误

[英]Segmentation fault when printing contents of a multidimensional array

I'm running the following C program and getting Segmentation fault: 11 . 我正在运行以下C程序,并出现Segmentation fault: 11

#include <stdio.h>
#include <stdlib.h>

#define SIZE 2

void print_array(double **arr, int size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%f\n", arr[i][j]);
        }
    }
}

int main(int argc, char **argv) {
    double mat[SIZE][SIZE] = {{1, 2}, {3, 4}};
    print_array((double **) mat, SIZE);
}

Could someone explain why this might be happening? 有人可以解释为什么会这样吗? I don't believe that I need to dynamically allocate memory for mat , since I'm passing it into print_array within the main() function. 我不认为我需要动态分配内存的mat ,因为我通过它进入print_array main()函数。

When changing the function signature of print_array() to print_array()的函数签名更改为

void print_array(int size, double arr[size][size])

the problem goes away. 问题消失了。

Still curious though... Why do I get the segmentation fault when casting mat as double ** and passing it into print_array() ? 虽然仍然好奇...为什么在将matdouble **并将其传递给print_array()时出现分割错误? At the end of the day, double arr[2][2] and double **arr with size 2 are the same thing, correct? 在一天结束时,大小为2的double arr[2][2]double **arr是同一件事,对吗?

You're getting undefined behavior since you're lying to the compiler about what your memory contains. 因为您向编译器说谎有关内存中包含的内容,所以您得到不确定的行为。

The in-memory format of mat is not the same as (double **) . mat的内存格式与(double **) The former is a compact square of double s, the latter is a pointer to a pointer. 前者是double的紧凑正方形,后者是指向指针的指针。 These are not the same. 这些不一样。

You can represent a 2D as an array of row (or column, if you feel like it) pointers, which makes double indexing work. 您可以将2D表示为行(或列,如果您喜欢的话)指针的数组,这使双重索引工作成为可能。 But that isn't the same thing as indexing into an actual array. 但这与索引到实际数组中不同。

UPDATE : I'm not sure if it's possible to come up with a function signature for a function that can access either an actual compact array, or one represented through pointers ... My suggestion would be to keep it simple and write two different functions for these different requirements: 更新 :我不确定是否可以为可以访问实际紧凑数组或通过指针表示的数组的函数提供函数签名...我的建议是保持简单并编写两个不同的函数针对这些不同的要求:

void print_matrix_compact(const double *el0, size_t size);
void print_matrix_indirect(const double **mtx, size_t size);

Here el0 is a pointer to element 0 of an actual ("compact") array, while mtx is a pointer to an array of pointers for the one stored as an array of arrays. 这里el0是指向实际(“紧凑”)数组的元素0的指针,而mtx是指向存储为数组数组的指针的指针数组的指针。 In both cases matrices are assumed to be square, with a size of size × size elements. 在这两种情况下,矩阵均假定为正方形,大小为size × size元素。

No, they are not the same. 不,他们不一样。

A double[size][size] is a contiguous block of memory containing double s where the compiler knows how to calculate the addresses out of the indices. double[size][size]是包含double的连续内存块,编译器知道如何从索引中计算地址。

A double ** is a pointer to a block of memory containing one or more pointers to blocks of double s. double **是指向内存块的指针,其中包含一个或多个double块的指针。

By accessing the double[size][size] as double ** you are interpreting your double values as pointers. 通过以double **访问double[size][size] ,您会将double值解释为指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM