我正在运行以下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);
}
有人可以解释为什么会这样吗?我不相信我需要为mat
动态分配内存,因为我已将其传递到 中的print_array
main()
函数。
将print_array()
的功能签名更改为
void print_array(int size, double arr[size][size])
问题消失了。
虽然仍然很好奇......为什么在将mat
作为double **
投射并将其传递到print_array()
时会出现细分错误?在一天结束时,double arr[2][2]
和double **arr
的大小为2是一回事,对吗?
答案 0 :(得分:4)
您正在获得未定义的行为,因为您正在向编译器说明您的内存包含的内容。
mat
的内存格式与(double **)
不同。前者是double
s的紧凑正方形,后者是指向指针的指针。这些都不一样。
您可以将2D表示为行(或列,如果您喜欢的话)指针的数组,这使得双索引工作。但这与索引到实际数组不同。
UPDATE :我不确定是否可以为一个函数提供函数签名,该函数可以访问实际的紧凑数组,也可以通过指针表示...我的建议是要保持简单,并为这些不同的要求编写两个不同的函数:
void print_matrix_compact(const double *el0, size_t size);
void print_matrix_indirect(const double **mtx, size_t size);
这里el0
是指向实际(“紧凑”)数组的元素0的指针,而mtx
是指向存储为数组数组的指针数组的指针。在这两种情况下,矩阵都假定为方形,大小为size
×size
个元素。
答案 1 :(得分:1)
不,他们不一样。
double
是一个包含double **
s的连续内存块,编译器知道如何计算索引中的地址。
double
是一个指向内存块的指针,其中包含一个或多个指向double[size][size]
s块的指针。
访问double **
作为double
,您将SELECT string_agg(txt, ', ') AS all_text
FROM (
SELECT jsonb_array_elements(qn)->>'text' AS txt
FROM templates
WHERE id = 1) sub;
值解释为指针。