c - C-函数定义具有用于参数的指针,在调用时传递的变量不是指针,而是编译和运行(有时)。怎么样?

标签 c function pointers compiler-errors cygwin

这是我的第一个问题,所以我希望我能很好地传达我的意思。
我的博士项目(航空航天)要求多年后,我最近回到C。我不是真正的软件开发人员,但通常可以通过。在过去的几年中,我一直在使用MATLAB,因此我发现向C的美好世界过渡以及更严格的规则有些棘手。
我已经获得了一些必须通过添加其他功能来适应的代码,而我对现有代码感到困惑。不幸的是,重写整个代码库是不可行的!
有一些函数在其定义/声明中显示为接受指针作为参数。但是,这些函数随后主要使用变量本身进行调用。功能主体中没有延迟。但是,与执行相同功能的MATLAB脚本相比,代码可以编译并成功运行,并且可以提供预期的输出。怎么会这样?
原始代码:

// "Toy Model" of original code - this works and produces expected outputs
// myFileName.c

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "myFileName.h" //Contains function declarations

#define FACTOR (4.5) //for example

//Original function definition
void originalFunction(const double * const P1, const double * const P2, double * P_res)
{
double P1nu[3];
double aMatrix[3][3];

/*Example of function body - this function calls another, using the input argument P1 which is not dereferenced in this function either*/
matMultVector(aMatrix, P1, P1nu);

P_res = P1nu * FACTOR;

}

int main()
{
double P1[3];
double P2[3];
double P_res[3];

P1[0] = 2;
P1[1] = 1;
P1[2] = 4;

P2[0] = 100;
P2[1] = 240;
P2[2] = 310;

originalFunction(P1, P2, P_res);

printf("Output:\n");
printf("P_resX: %lf\n", P_res[0]);
printf("P_resY: %lf\n", P_res[1]);
printf("P_resZ: %lf\n", P_res[2]);
)

return (0);
}
然后,我按照相同的结构添加了新功能:
新代码:
// "Toy Model" of new code - produces cygwin error at compile time
// myFileName.c

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "myFileName.h" //Contains function declarations

#define FACTOR (4.5) //for example

//Original function definition
void originalFunction(const double * const P1, const double * const P2, double * P_res)
{
double P1nu[3];
double aMatrix[3][3];

/*Example of function body - this function calls another, using the input argument P1, which is not dereferenced in this function either*/
matMultVector(aMatrix, P1, P1nu);

P_res = P1nu * FACTOR;

}

// My new function definition
void myFunction(const double * const P1, const double * const P2, double * myP_res)
{

double* P3; //intermediate variable.

originalFunction(P1, P2, P3);

myP_res = P3;

}

int main()
{
double P1[3];
double P2[3];
double P_res[3];
double myP_res[3];

P1[0] = 2;
P1[1] = 1;
P1[2] = 4;

P2[0] = 100;
P2[1] = 240;
P2[2] = 310;

originalFunction(P1, P2, P_res);
myFunction(P1, P2, myP_res);

printf("Output:\n");
printf("P_resX: %lf\n", P_res[0]);
printf("P_resY: %lf\n", P_res[1]);
printf("P_resZ: %lf\n", P_res[2]);
printf("myP_resX: %lf\n", myP_res[0]);
printf("myP_resY: %lf\n", myP_res[1]);
printf("myP_resZ: %lf\n", myP_res[2]);
)

return(0);
}
这可以编译,但是当我尝试运行它时,出现cygwin错误:
0 [main] myFileName 30504 cygwin_exception::open_stackdumpfile: Dumping stack trace to myFileName.exe.stackdump
研究这个告诉我,当一个函数在预期的时候没有收到指针时,就会发生这种情况。但是我无法弄清楚为什么原来的功能不会发生这种情况,以及为什么我的功能会发生这种情况。
我也尝试了在上面没有指针的情况下定义P3,但是随后在编译时出现了不兼容的类型错误。
有什么想法吗?
非常感谢!
编辑:经过评论后,我意识到这不是一个最低限度的工作示例,很抱歉。我试图简化代码以提出问题,但并没有确保简化后的代码实际上是正确的,并且其中存在错误,这些错误已被其他人正确地发现,但在原始版本中不存在代码,而不是我的问题的一部分(例如FACTOR乘法)。我现在不打算编辑代码,因为我认为这会引起更多困惑。

最佳答案

在原始代码中,P1P2P_res是数组:

double P1[3];
double P2[3];
double P_res[3];
除非它是sizeof_Alignof或一元&运算符的操作数,或者是用于初始化声明中的字符数组的字符串文字,否则,将转换类型为“T的N元素数组”的表达式(“decay ”)表示为“指向T的指针”类型的表达式,该表达式的值将是数组第一个元素的地址。所以,当你打电话
originalFunction(P1, P2, P_res);
完全等同于写作
originalFunction( &P1[0], &P2[0], &P_res[0] );
originalFunction接收的是三个指针值,而不是数组。
当您添加代码时
double* P3; //intermediate variable.

originalFunction(P1, P2, P3);
P3是一个指针,但尚未设置为指向有意义的任何地方-它是无效的指针。当您尝试通过该指针访问任何内存时,可能会遇到运行时错误。
您说原始代码会编译并产生预期的输出,但这是不可能的,因为
P_res = P1nu * FACTOR;
没有按照你的想法做。它将P1nu的第一个元素的地址乘以FACTOR并将结果指针值分配给P_res。它不是将P1nu的每个元素乘以FACTOR并将结果分配给P_res的相应元素。您将需要明确地写出:
for ( size_t i = 0; i < NUM_ELEMENTS; i++ )
  P_res[i] = P1nu[i] * FACTOR;

关于c - C-函数定义具有用于参数的指针,在调用时传递的变量不是指针,而是编译和运行(有时)。怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62677194/

相关文章:

从 int 转换为(16 位)__m128i

javascript - 作为参数传递时如何调用函数引用

c - 为什么这会返回 NULL

c - 字符串指针问题,未正确指向

c - GDB 无法插入断点,无法访问地址 XXX 处的内存?

c - 如何在编写 C 代码时使用随机性?

不太明白指针

javascript - 函数不断重复运行 Jquery

javascript - 为什么当我将一个变量复制到 window 对象时它变成了 public?

c++ - 为什么允许我为包含常量指针的 vector 分配新地址?