C ,关于指针(或指向指针的指针?)、**和 malloc
C , regarding pointers (or pointers to pointers?), **, and malloc
如标题所述,我有一个关于使用 * 两次的问题,例如在以下代码的 main 函数中。它 运行,但我不明白为什么在这里使用 **。我想要的是一个 SPPoints 数组,大小为 n,其中 parr 是基地址。为什么在这种情况下**对和*错?谢谢。
SPPoint代码:
struct sp_point_t
{
double* data;
int dim;
int index;
};
SPPoint* spPointCreate(double* data, int dim, int index)
{
if (data == NULL || dim <= 0 || index < 0)
{
return NULL;
}
SPPoint* point = malloc(sizeof(*point));
if (point == NULL)
{
return NULL;
}
point->data = (double*)malloc(dim * sizeof(*data));
for (int i = 0; i < dim; i++)
{
point->data[i] = data[i];
}
point->dim = dim;
point->index = index;
return point;
}
这是主要功能:
int main()
{
int n, d, k;
scanf("%d %d %d", &n, &d, &k);
double* darr = malloc(d * sizeof(double));
if (darr == NULL)
{
return 0;
}
SPPoint** parr = malloc(n * sizeof(SPPoint*));
if (parr == NULL)
{
return 0;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < d; j++)
{
scanf(" %lf", &darr[j]);
}
parr[i] = spPointCreate(darr, d, i);
}
}
数组的行为类似于指针。例如,int a [] 与 int* a 非常相似。 SPPoint returns 中的每个函数都是一个指向 SPPoint 结构的指针。指向 SPPoint 的指针数组可以写成指向指向 SPPoint 的指针的指针。使用 malloc 命令,您指定一定数量的内存(足以容纳 n 个指向 SPPoint 的指针)用于存储指向 SPPoint 结构的指针。
然而,并不是所有的指针都是数组。 SPPoint** parr 充当一个数组,其中包含指向 SPPoint 类型的单个结构的指针。
数组的行为可能与指针不同,尤其是用于字符串时。
使用指向 SPPoint 的指针(就像您现在这样)的好处在于您可以查看或修改单个元素而无需复制整个结构。
当使用动态分配的数组时,通常 "handled" 有一个指向数组第一个元素的指针,并且还有一些知道长度的方法,例如显式存储长度,或者有一个终结哨兵。
因此,对于代码中动态分配的 SPPoint *
数组,指向其中第一个数组的指针的类型为 SPPoint * *
您现有的代码创建了一个 SPPoint *
数组,即指针数组。这些指针中的每一个都指向 SPPoint
的一个动态分配实例,即您为每个条目单独分配。
这是可行的,但您指出您想要一个 SPPoint
的数组,在这种情况下,指向第一个元素的指针的类型为 SPPoint *
.
为了有这样一个数组,是单内存分配。因此,您需要重新设计 spPointCreate
函数。目前,它仅为单个 SPPoint
分配内存并进行初始化。相反,您希望将分配与初始化分开,因为您只需要一次分配但需要多次初始化。您的程序逻辑将如下所示:
- 为
n
SPPoint
s 分配足够大的内存块
- 在分配的space
中初始化每个SPPoint
如果您已经尝试过但卡住了,那么 post 一个显示您的代码并解释您卡住的地方的新问题。
如标题所述,我有一个关于使用 * 两次的问题,例如在以下代码的 main 函数中。它 运行,但我不明白为什么在这里使用 **。我想要的是一个 SPPoints 数组,大小为 n,其中 parr 是基地址。为什么在这种情况下**对和*错?谢谢。
SPPoint代码:
struct sp_point_t
{
double* data;
int dim;
int index;
};
SPPoint* spPointCreate(double* data, int dim, int index)
{
if (data == NULL || dim <= 0 || index < 0)
{
return NULL;
}
SPPoint* point = malloc(sizeof(*point));
if (point == NULL)
{
return NULL;
}
point->data = (double*)malloc(dim * sizeof(*data));
for (int i = 0; i < dim; i++)
{
point->data[i] = data[i];
}
point->dim = dim;
point->index = index;
return point;
}
这是主要功能:
int main()
{
int n, d, k;
scanf("%d %d %d", &n, &d, &k);
double* darr = malloc(d * sizeof(double));
if (darr == NULL)
{
return 0;
}
SPPoint** parr = malloc(n * sizeof(SPPoint*));
if (parr == NULL)
{
return 0;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < d; j++)
{
scanf(" %lf", &darr[j]);
}
parr[i] = spPointCreate(darr, d, i);
}
}
数组的行为类似于指针。例如,int a [] 与 int* a 非常相似。 SPPoint returns 中的每个函数都是一个指向 SPPoint 结构的指针。指向 SPPoint 的指针数组可以写成指向指向 SPPoint 的指针的指针。使用 malloc 命令,您指定一定数量的内存(足以容纳 n 个指向 SPPoint 的指针)用于存储指向 SPPoint 结构的指针。
然而,并不是所有的指针都是数组。 SPPoint** parr 充当一个数组,其中包含指向 SPPoint 类型的单个结构的指针。
数组的行为可能与指针不同,尤其是用于字符串时。
使用指向 SPPoint 的指针(就像您现在这样)的好处在于您可以查看或修改单个元素而无需复制整个结构。
当使用动态分配的数组时,通常 "handled" 有一个指向数组第一个元素的指针,并且还有一些知道长度的方法,例如显式存储长度,或者有一个终结哨兵。
因此,对于代码中动态分配的 SPPoint *
数组,指向其中第一个数组的指针的类型为 SPPoint * *
您现有的代码创建了一个 SPPoint *
数组,即指针数组。这些指针中的每一个都指向 SPPoint
的一个动态分配实例,即您为每个条目单独分配。
这是可行的,但您指出您想要一个 SPPoint
的数组,在这种情况下,指向第一个元素的指针的类型为 SPPoint *
.
为了有这样一个数组,是单内存分配。因此,您需要重新设计 spPointCreate
函数。目前,它仅为单个 SPPoint
分配内存并进行初始化。相反,您希望将分配与初始化分开,因为您只需要一次分配但需要多次初始化。您的程序逻辑将如下所示:
- 为
n
SPPoint
s 分配足够大的内存块
- 在分配的space 中初始化每个
SPPoint
如果您已经尝试过但卡住了,那么 post 一个显示您的代码并解释您卡住的地方的新问题。