C、关于指针(或指向指针的指针?)、***和malloc

C、关于指针(或指向指针的指针?)、***和malloc,c,memory,malloc,dynamic-memory-allocation,C,Memory,Malloc,Dynamic Memory Allocation,正如在标题中所说,我有一个关于两次使用*的问题,就像在下面代码的主要函数中一样。它确实运行,但我不明白为什么在这里使用**。我想要的是一个大小为n的SPPoints数组,其中parr是基本地址。为什么在这种情况下**是对的*是错的?谢谢 点代码: struct sp_point_t { double* data; int dim; int index; }; SPPoint* spPointCreate(double* data, int dim, int index)

正如在标题中所说,我有一个关于两次使用*的问题,就像在下面代码的主要函数中一样。它确实运行,但我不明白为什么在这里使用**。我想要的是一个大小为n的SPPoints数组,其中parr是基本地址。为什么在这种情况下**是对的*是错的?谢谢

点代码:

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;
}
struct sp\u point\t
{
双*数据;
int-dim;
整数指数;
};
SPPoint*spPointCreate(双*数据、整型尺寸、整型索引)
{
如果(数据==NULL | |尺寸数据=(双*)malloc(尺寸*尺寸(*数据));
对于(int i=0;i数据[i]=数据[i];
}
点->尺寸=尺寸;
点->索引=索引;
返回点;
}
这是主要功能:

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);
    }
}
intmain()
{
int n,d,k;
scanf(“%d%d%d”、&n、&d、&k);
double*darr=malloc(d*sizeof(double));
如果(darr==NULL)
{
返回0;
}
SPPoint**parr=malloc(n*sizeof(SPPoint*));
if(parr==NULL)
{
返回0;
}
对于(int i=0;i
数组的行为可以类似于指针。例如,int a[]与int*a非常相似。SPPoint中的每个函数都返回指向SPPoint结构的指针。指向SPPoint的指针数组可以写成指向SPPoint的指针。使用malloc命令,可以指定一定量的内存(足以容纳n个指向SPPoint的指针)用于存储指向SPPoint结构的指针

但是,并非所有指针都是数组。SPPoint**parr充当一个数组,其中包含指向SPPoint类型的单个结构的指针

数组的行为可能与指针不同,尤其是用于字符串时


使用指向SPPoint的指针(就像现在这样)是有利的,因为您可以查看或修改单个元素,而不必复制整个结构。

当使用动态分配的数组时,它通常是“处理”的通过有一个指向数组第一个元素的指针,并且还有一些知道长度的方法,比如显式存储长度,或者有一个结束哨兵

因此,对于代码中动态分配的
SPPoint*
数组,指向其中第一个数组的指针的类型为
SPPoint**

现有代码创建一个
SPPoint*
数组,即指针数组。每个指针指向一个动态分配的
SPPoint
实例,即每个条目都有单独的分配

这是可行的,但您指出您需要一个
SPPoint
数组,在这种情况下,指向第一个元素的指针的类型为
SPPoint*

为了拥有这样一个数组,它是一个单一的内存分配。因此,您需要重新设计
spPointCreate
函数。目前,该函数只为单个
SPPoint
分配内存并进行初始化。相反,您希望将分配与初始化分开,因为您只需要一个分配,但需要mult多次初始化。您的程序逻辑将如下所示:

  • n
    SPPoint
    s分配一块足够大的内存
  • 初始化分配空间内的每个
    SPPoint

如果您尝试了此方法但遇到了问题,请发布一个新问题,显示您的代码并解释您遇到问题的原因。

SPPoint**parr;
是指向(一组)指针的指针
SPPoint*spPointCreate(…)<代码> BTW: SPONT不是TyPoffff.你使用C++编译器吗?它在头文件中,很抱歉没有包含它.它在哪里并不重要:在C中,结构定义不等同于TyffFED结构.我明白,这很有趣,因为我的课程工作人员给了我们下面的标题文件:(typedef struct sp_point_t SPPoint;),并告诉我们需要在C文件中有这样的结构定义。因此,如果它的类型定义在头文件中,它也必须在C文件中有这样的定义吗?数组不能被视为指针,就像int可以被视为double一样…实际上,将数组与指针混淆会导致各种误解和错误伴随而来的错误。@Rusty,你还是不明白。数组和指针是完全不同的东西。指针不是数组,指针也不是数组,或者数组的行为类似于指针。实际情况是,当计算数组类型的表达式时,结果是指向数组的第一个元素的指针当然,这样一个指针的行为和指针完全一样。这一点需要理解,因为如果你不理解的话,关于C的许多事情似乎是不一致的。@Rusty数组不存储内存地址(除非它是指针数组)。数组有地址,但int和任何其他object都有地址。@M.M.说,数组不存储内存地址,除非它们的元素是指针。您提出的反对意见围绕着我前面提到的一些误解。其中:(I)没有C函数接受数组作为参数;(ii)索引运算符(
[]
)从技术上讲,它是一个指针运算符,而不是数组运算符。您没有提出这个运算符,但我们在这里经常看到的另一个运算符是错误的期望,即2D数组对应于所谓的双指针。这也是C没有完整数组赋值的原因。