结构体中的数组

发布于 2024-10-18 22:17:30 字数 567 浏览 0 评论 0原文

我是 C 新手,在嵌入结构时遇到数组类型问题。以下是我的问题的示例:

typedef struct {
    double J[151][151];
} *UserData;

static int PSolve(void *user_data, N_Vector solution)
{
UserData data;
data = (UserData) user_data;

double J[151][151];
J = data->J;

/* Solve a matrix equation that uses J, stored in 'solution' */

return(0);
}

当我尝试编译此问题时,我得到 错误:从类型“double (*)[151]”分配给类型“double[151][151]”时出现不兼容的类型

我当前的解决方法是将“J[x][y]”替换为“data-” > J[x][y]' 存在于求解矩阵方程的代码中,但分析表明这样做效率较低。

将参数更改为 PSolve 不是一个选项,因为我使用的是 sundials-cvode 求解器,它规定了参数的类型和顺序。

I'm new to C and having a problem with array types when embedded in structures. The following is an example of my issue:

typedef struct {
    double J[151][151];
} *UserData;

static int PSolve(void *user_data, N_Vector solution)
{
UserData data;
data = (UserData) user_data;

double J[151][151];
J = data->J;

/* Solve a matrix equation that uses J, stored in 'solution' */

return(0);
}

When I try to compile this I get
error: incompatible types when assigning to type ‘double[151][151]’ from type ‘double (*)[151]’

My current workaround for this has been to replace 'J[x][y]' by 'data->J[x][y]' in the code to solve the matrix equation, but profiling has shown this to be less efficient.

Changing the arguments to PSolve is not an option because I'm using the sundials-cvode solver which prescribes the type and order of the arguments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风疏影 2024-10-25 22:17:30
typedef struct {
    double J[151][151];
} UserData; // This is a new data structure and should not a pointer!

static int PSolve(void *user_data, N_Vector solution)
{
UserData* data; // This should be a pointer instead!
data = (UserData*) user_data;

double J[151][151];
memcpy(J, data->J, sizeof(double) * 151 * 151); // use memcpy() to copy the contents from one array to another

/* Solve a matrix equation that uses J, stored in 'solution' */

return(0);
}
typedef struct {
    double J[151][151];
} UserData; // This is a new data structure and should not a pointer!

static int PSolve(void *user_data, N_Vector solution)
{
UserData* data; // This should be a pointer instead!
data = (UserData*) user_data;

double J[151][151];
memcpy(J, data->J, sizeof(double) * 151 * 151); // use memcpy() to copy the contents from one array to another

/* Solve a matrix equation that uses J, stored in 'solution' */

return(0);
}
我一直都在从未离去 2024-10-25 22:17:30

问题的根本原因是数组类型无法在 C 中直接分配。您必须显式使用 memcpy(),如 karlphillip 的答案显示。

但请注意,执行复制可能会消除您在函数其余部分中获得的优化收益。据推测,solution 参数是一个指针,优化器担心 user_data / datasolution 之间潜在的别名>。作为替代方案,如果您有支持 C99 的 restrict 关键字的编译器,请在参数上使用该限定符:

static int PSolve(void * restrict user_data, N_Vector restrict solution)

这向编译器保证这些指针不会别名,并且应该允许您直接使用 data->J 而无需牺牲编译器优化。

某些编译器使 restrict 关键字在 C89 模式下可用,其拼写如 __restrict - 请参阅编译器文档以了解更多详细信息。

The root cause of your issue is that array types cannot be directly assigned in C. You must explicitly use memcpy(), as karlphillip's answer shows.

Note however that performing the copy may wipe out the optimisation gains you make in the remainder of the function. Presumably, the solution argument is a pointer, and the optimiser is worried about potential aliasing between user_data / data and solution. As an alternative, if you have a compiler that supports C99's restrict keyword, is to use that qualifier on the arguments:

static int PSolve(void * restrict user_data, N_Vector restrict solution)

This promises the compiler that those pointers do not alias, and should allow you to directly use data->J without sacrificing the compiler optimisations.

Some compilers make the restrict keyword available in C89 mode under a spelling such as __restrict - consult your compiler documentation for more details.

2024-10-25 22:17:30

您不能分配给数组。你应该查一下 C 语言中数组和指针之间的区别。

你的代码中需要的就是这样的:

double (*J)[151] = data->J;

这是一个指向长度为 151 的数组的指针。或者,如果您只想使用 typedef

typedef double line[151];
line *J = data->J;

,则不应复制数据,而只复制指向数据的指针。

编辑:但是看到整个答案,我认为所有这些都纯粹是猜测你的瓶颈可能在哪里。它可能在任何地方,例如,您正在以“错误的方式”、按列或其他方式访问矩阵。或者从内存中提取数据只是主导你的计算。

也许考虑查看编译器生成的汇编程序(选项 -S),看看是否有可疑之处。

You can't assign to an array. You should look up about the difference between arrays and pointers in C.

What you need in your code is just something like this:

double (*J)[151] = data->J;

that is a pointer to arrays of length 151. Or if you'd like with typedefs

typedef double line[151];
line *J = data->J;

that's all, you should not copy the data but just the pointer to the data.

Edit: But seeing the whole thread of answers, I think all of that is pure speculation where your bottleneck might be. It could just be anywhere, e.g that you are accessing the matrix the "wrong way round", column wise, or whatever. Or that pumping the data from memory is just dominating your computation.

Perhaps consider to look into the assembler that your compiler produces (option -S) to see if there is something fishy.

弱骨蛰伏 2024-10-25 22:17:30

尝试将局部变量 double J[151][151] 定义为 double **J。

Try defining local variable double J[151][151] as double **J.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文