释放动态分配数组后的C分段错误
我试图创建动态分配的集群阵列,其中每个集群都有自己的动态分配的点阵列释放动态分配数组后的C分段错误,c,arrays,struct,segmentation-fault,C,Arrays,Struct,Segmentation Fault,我试图创建动态分配的集群阵列,其中每个集群都有自己的动态分配的点阵列 typedef struct Point { int ID; //each point has some ID and XY coordinates int X; int Y; }Point; typedef struct Cluster { int size; //how many points can cluster hold int count; //how m
typedef struct Point
{
int ID; //each point has some ID and XY coordinates
int X;
int Y;
}Point;
typedef struct Cluster
{
int size; //how many points can cluster hold
int count; //how many points cluster actually holds
Point *points; //dynamically allocated array of points
}Cluster;
我能够初始化群集阵列并使用此函数填充它:
void fill_array(Cluster **arr, int how_many_clusters)
{
*arr = (Cluster *)malloc(sizeof(Cluster) * how_many_clusters);
for(int i = 0; i < how_many_clusters; i++)
{
Point point;
point.ID = i;
point.X = i * 2;
point.Y = i * 3;
(*arr)[i].size = 1;
(*arr)[i].count = 1;
(*arr)[i].points = (Point *)malloc(sizeof(Point));
(*arr)[i].points[i] = point;
}
}
当我编译并运行这个程序时,它在free
ing的第二次迭代中崩溃,出现了分段错误。在过去的两天里,我一直在互联网上搜寻,但没有发现我做错了什么。
有人能指出我看不出的错误在哪里吗
(*arr)[i].points[i] = point;
这看起来不对。应该是
(*arr)[i].points[0] = point;
以下位:
(*arr)[i].points = (Point *)malloc(sizeof(Point));
(*arr)[i].points[i] = point;
没有分配正确的内存量
i
将是一些大于零的数字,但您只为一个点
分配了空间。你正在粉碎你的堆,随后将发生崩溃。没有必要强制执行malloc的返回,这是不必要的。请参阅:malloc
返回与任何指针兼容的void*
。石膏只能使水变得浑浊。只需分配指针点
,然后对取消引用的指针调用sizeof
,例如:
(*arr)[i].points = malloc (sizeof *(*arr)[i].points);
虽然分配语句正确,但它完全无法验证分配是否成功,相反,请检查malloc
返回的值是否为NULL
,例如
if (!((*arr)[i].points = malloc (sizeof *(*arr)[i].points))) {
perror ("malloc failed - points");
exit (EXIT_FAILURE);
}
if (!(*arr = malloc (sizeof **arr * nclusters))) {
perror ("malloc failed - nclusters");
exit (EXIT_FAILURE);
}
*(*arr)[i].points = point; /* copy struct to allocated memory */
分配*arr
时也一样,例如
if (!((*arr)[i].points = malloc (sizeof *(*arr)[i].points))) {
perror ("malloc failed - points");
exit (EXIT_FAILURE);
}
if (!(*arr = malloc (sizeof **arr * nclusters))) {
perror ("malloc failed - nclusters");
exit (EXIT_FAILURE);
}
*(*arr)[i].points = point; /* copy struct to allocated memory */
(注意:有多少个集群被缩短为nclusters
,我们不是在写小说)
你的主要问题是:
(*arr)[i].points[i] = point;
您只为一个点
结构分配内存,因此点[i]
毫无意义。您分配了sizeof(Point)
——您认为有多少个
由于您的目标是将点
复制到指针持有的地址处新分配的内存块(*arr)[i]。点
,“如何访问(或设置)指针引用(例如指向)的值?”(答案:,您取消指针引用以获得值)
这就是你在这里需要做的。没有额外的[…]
附加到解除引用(*arr)[i]的末尾。点
,只需用一元'*'
解除引用即可,例如
if (!((*arr)[i].points = malloc (sizeof *(*arr)[i].points))) {
perror ("malloc failed - points");
exit (EXIT_FAILURE);
}
if (!(*arr = malloc (sizeof **arr * nclusters))) {
perror ("malloc failed - nclusters");
exit (EXIT_FAILURE);
}
*(*arr)[i].points = point; /* copy struct to allocated memory */
将这些部分放在一起,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int ID; //each point has some ID and XY coordinates
int X;
int Y;
} Point;
typedef struct {
int size; //how many points can cluster hold
int count; //how many points cluster actually holds
Point *points; //dynamically allocated array of points
} Cluster;
void fill_array (Cluster **arr, int nclusters)
{
if (!(*arr = malloc (sizeof **arr * nclusters))) {
perror ("malloc failed - nclusters");
exit (EXIT_FAILURE);
}
for (int i = 0; i < nclusters; i++)
{
Point point;
point.ID = i;
point.X = i * 2;
point.Y = i * 3;
(*arr)[i].size = 1;
(*arr)[i].count = 1;
if (!((*arr)[i].points = malloc (sizeof *(*arr)[i].points))) {
perror ("malloc failed - points");
exit (EXIT_FAILURE);
}
*(*arr)[i].points = point; /* copy struct to allocated memory */
}
}
int main (void) {
Cluster *clusters;
int clusters_count = 20;
fill_array (&clusters, clusters_count);
for(int i = 0; i < clusters_count; i++)
{
free(clusters[i].points); //crash point
clusters[i].points = NULL;
}
free (clusters);
return 0;
}
始终确认已释放所有已分配的内存,并且没有内存错误
仔细检查一下,如果您还有其他问题,请告诉我。没有,但它有效。我尝试了printf()
在每一行进行调试。崩溃点ts实际上位于main
@user3670471如果它没有在这条线上崩溃,并不意味着这条线本身就正常。用0
替换第二个i
,它就会工作。是的,现在我看到问题了。非常感谢。(*arr)[i]。点[i]=点代码>写入超出范围。您只为一个点分配了空间