内存动态分配问题

Posted

技术标签:

【中文标题】内存动态分配问题【英文标题】:Problem with dynamic allocation of memory 【发布时间】:2022-01-22 19:35:39 【问题描述】:

到目前为止,我确实为这样的矩阵分配了内存:

int **p,n;
scanf("%d",&n);
p=malloc(n*sizeof(int));
for(int i=0;i<n;i++)
p[i]=malloc(n*sizeof(int));
但有人告诉我这样做:
int **p,n;
scanf("%d",&n);
p=malloc(n*sizeof*p);
for(int i=0;i<n;i++)
p[i]=malloc(n*sizeof*p);

sizeof(p) 不是 0 因为没有分配?? 哪个好?

【问题讨论】:

这是错误的-p=malloc(n*sizeof(int));。应该是-p=malloc(n*sizeof(int *)); 你能告诉我为什么吗? 因为p不是指向int的指针,而是指向int的指针。 第二版代码的好处就是可以避免这样的错误。此外,如果您更改 p 的类型,则无需将调用调整为 malloc 第三种选择:int (*p)[n] = malloc(n * sizeof *p); 【参考方案1】:

在第一个代码sn-p中,这句话是错误的:

p=malloc(n*sizeof(int));

因为p的类型是int **,所以,p可以是指向int *的指针 类型。应该是:

p = malloc (n * sizeof (int *));
                        ^^^^^

在第二个代码 sn-p 中,分配给 p 是正确的,因此 - sizeof*p*p 的类型是 int *。所以,sizeof*p 等价于sizeof (int *)

但在第二个代码 sn-p 中,这是错误的:

p[i]=malloc(n*sizeof*p);

因为p[i] 的类型是int *,即指向int 的指针。所以,它可以指向一个整数。因此,您应该分配n * sizeof (int) 的内存。应该是

p[i] = malloc (n * sizeof *p[i]);

这里,n * sizeof *p[i] 等价于n * sizeof (int),因为*p[i] 的类型是int

使用您想要的任何样式都可以选择。事实上,你应该很好地理解你在做什么以及它是如何工作的,因为缺乏理解可能会导致你选择的任何风格的错误(你可以看到代码 sn -ps 你已经展示了)。

【讨论】:

这实际上是一个很好的例子,说明了为什么每种风格都有其缺陷。【参考方案2】:

首先,p=malloc(n*sizeof(int)); 是错误的 - 您分配的不是二维数组而是一个指针数组,每个指针都指向一个 int 数组。这需要p=malloc(n*sizeof(int*)); 才能使第一个示例正确。

除了那个错误,这是一个主观编码风格的问题。有些人更喜欢写malloc(n*sizeof*p);,因为sizeof *p 给出了指向项目的大小。这是因为sizeof 没有评估副作用,因此实际上没有发生指针取消引用。大小在编译时计算。

第三种样式也是可能的:p=malloc( sizeof(int*[n]) );。在这里,您更明确地声明了一个数组。使用这三种风格中的哪一种是主观的,主要是见仁见智。

如果您想分配相邻分配的实际二维数组,则需要按照此处的建议进行操作:Correctly allocating multi-dimensional arrays

【讨论】:

以上是关于内存动态分配问题的主要内容,如果未能解决你的问题,请参考以下文章

动态内存分配(c语言)

C语言中的动态内存分配的用法举例

连续内存分配:内存碎片与分区的动态分配

在 C++ 中的 2D 动态内存分配数组中释放分配的内存

C++ 动态分配内存

零基础学C语言知识总结十一:动态内存分配!