我有一个带有指针组件的结构。指针将指向一个数组,该数组的大小将在声明结构后确定。我需要对内存进行 malloc,然后将其分配给指针。以某种方式通过函数调用传递此指针会导致问题。这是一个简单的例子,它重现了我的错误:
#include <stdlib.h>
#include <stdio.h>
typedef struct mystruct mystruct;
struct mystruct{
int dim;
double *dubarr;
double dub;
};
int getarr(int *dim, double *dubarr){
*dim = 2; /* The value of dim is not known until this function is called */
dubarr = malloc(*dim * sizeof(double));
double test;
int i;
for(i=0;i<*dim;i++)
{
dubarr[i] = (i+1)*7.0;
test = dubarr[i];
printf("dubarr[%i] = %.15en", i, test);
}
return 1;}
int initmystruct(mystruct *data){
getarr(&(data->dim),data->dubarr);
data->dub = (data->dim)*((data->dubarr)[0]);
return 1;}
int main(void){
mystruct data;
initmystruct(&data);
double test;
int i;
for(i=0;i<data.dim;i++)
{
test = (data.dubarr)[i];
printf("dubarr[%i] = %.15en", i, test);
}
/* I would do "free(data.dubarr);" here but it causes a crash */
return 1;}
代码编译时没有警告,但data.dubarr
组件不会通过函数调用维护其值。这是输出:
dubarr[0] = 7.000000000000000e+00
dubarr[1] = 1.400000000000000e+01
dubarr[0] = 2.002400628035951e+176
dubarr[1] = 2.186218092030684e-154
请指出我所有的错误:)
C 使用按值传递。所以在这里:
int getarr(int *dim, double *dubarr)
该函数接收dubarr
,一个指向double
的指针,按值传递。因此,无论功能分配给dubarr
什么,都无法在getarr
之外看到。请注意,getarr
的实现修改了dubarr
,但调用方不会看到这些修改。
将其与您处理dim
的方式形成对比,您修改*dim
。同样,请查看代码中对getarr
的调用:
getarr(&(data->dim), data->dubarr);
观察这两个参数是如何区别对待的。对于第一个参数,传递变量的地址,对于第二个参数,传递指针的值。
相反,您需要:
int getarr(int *dim, double **dubarr)
然后像这样分配给*dubarr
:
*dubarr = malloc(...);
并像这样称呼getarr
:
getarr(&(data->dim), &(data->dubarr));