我有这个循环,给出了seg。故障。
s->c = malloc(width * height * sizeof(double));
if (s->c == NULL) { puts("malloc failed"); exit(1); }
for (int n = 0; n < width; n++) {
for (int m = 0; m < height; m++) {
d = (&s->c)[m][n];
printf("d %f\n", d);
printf("m %i\n", m);
printf("n %i\n", n);
}
}
内部s-&gt; c是:
double* c;
执行时只输出:
d 27.000000
m 0
n 0
然后是seg。故障。
当我将s-&gt; c视为一维数组时,它有效,但我真的希望将其视为二维数组。
当c指针在结构中时,这可能吗?
如果是,(&s->c)[m][n]
是否正确访问元素?
桑德拉
答案 0 :(得分:5)
问题是编译器不知道矩阵的维数。
如果您有double tab[m][n]
,则可以tab[row][col]
*(tab + (row * n) + col)
在您的情况下,您只有double *tab;
可以被视为指向元素tab[0][0]
的指针,没有关于矩阵维度的信息,编译器无法计算正确的地址。
您可以自己计算地址(例如使用宏)但会丢失漂亮的tab[x][y]
语法。
我很惊讶它编译。您应该至少收到一条关于隐式地向指针投射双精度的警告。
答案 1 :(得分:4)
我很惊讶它甚至编译。显然c
是double*
,因此(&s->c)[m]
是m double
。现在,double
没有operator[]
,因此我看不到[n]
中(&s->c)[m][n]
部分的合法性。
据推测,您已经以不同方式宣布c
。有不同的解决方案:指向指针的指针,指向双精度数组的指针,指向双精度的指针数组等。如果分配与声明匹配,则所有可能都有效。在您的情况下,分配将与声明不匹配。
答案 2 :(得分:2)
访问数组元素的正确方法是
d = s->c[m * width + n];
这就是将它视为一维数组的意思吗?
答案 3 :(得分:1)
使用
访问元素double d = s->c[m*width+n];
也许通过内联函数,以避免意外行为。
编译器不知道您想要的2D数组的宽度。它可能将(&amp; s-&gt; c)[m] [n]解释为s-> c [m + n],或者作为完全不同的东西。
答案 4 :(得分:1)
简短回答:您不能将其视为2D数组,至少不是您期望的方式。
写作的原因
(&s->c)[m][n]
不起作用可以如下所示。假设s->c
的地址是0x00080004,s->c
指向的动态分配的内存的地址是0x00001000。
(&s->c)[m][n]
评估为*(*(&s->c + m) + n)
; &s->c
的计算结果为0x00080004
; (&s->c + m)
的计算结果为0x00080004+m
; *(&s->c + m)
计算0x00080004+m
指向的值的值。如果m
为0,则0x00080004+m
指向0x00001000
,这是您动态分配的内存的地址(*(&x) == x
)。如果m
是任何其他值,则0x00080004+m
随机指向某处; (*(&s->c + m) + n)
评估为0x00080004+m
个点,以n
计算。如果m
为0,则值为0x00001000+n
,或者是动态分配的内存的偏移量。如果m
不为0,那么该值是随机的; *(*(&s->c) + m) + n)
尝试取消引用上述值。如果m
为0,则结果是动态分配的数组中元素的值。如果m
不为0,则结果为......其他内容。在你的情况下,一个段错误。 如果要动态分配2D数组,则必须使用指向指针的指针并按步骤分配,如下所示:
struct {
...
double **c;
...
} *s;
...
/**
* Notes: type of s->c is double **
* type of *(s->c) and s->c[i] is double *
* type of *(s->c[i]) and s->c[i][j] is double
*/
s->c = malloc(sizeof *(s->c) * rows);
if (s->c)
{
for (i = 0; i < rows; i++)
{
s->c[i] = malloc(sizeof *(s->c[i]) * columns);
if (s->c[i])
{
// initialize s->c[i][0] through s->c[i][columns-1]
}
}
}
答案 5 :(得分:0)
如果您想将s-&gt; c作为一维数组分配,那么您可以定义一个为您完成工作的宏(但您需要知道第二个维度):
#define AR(M, X, Y) ((M)[(Y) + dimy * (X)])
答案 6 :(得分:0)
我很惊讶没有人提到boost::multi_array_ref:
#include <iostream>
#include <boost/multi_array.hpp>
int main()
{
int rows = 4, cols = 3;
// Allocate one big block of contiguous data for entire multi-array
double* arrayData = new double[rows*cols];
if (arrayData)
{
boost::multi_array_ref<double, 2>
arrayRef(arrayData, boost::extents[rows][cols]);
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
arrayRef[row][col] = row*cols + col;
std::cout << arrayRef[row][col] << " ";
}
std::cout << std::endl;
}
}
delete [] arrayData;
}
您也可以使用boost :: multi_array并动态调整大小:
boost::multi_array_ref<double, 2> marray;
marray.resize(boost::extents[rows][cols]);