c上的代码崩溃,很可能与malloc有关?

Posted

技术标签:

【中文标题】c上的代码崩溃,很可能与malloc有关?【英文标题】:Code crashes on c, most likely something to do with malloc? 【发布时间】:2017-05-12 05:38:12 【问题描述】:

这是非常基本的,但我已经尝试解决了几个小时,但没有成功。这段代码应该从用户输入中读取 3 个整数,然后根据整数进行点数(n = 多少,d = 维度,k 与这部分无关)并创建它们的数组。由于某种原因,它在第二个循环中崩溃,无法创建第二个点,但我不确定为什么。我认为这可能与 malloc 有关,但我完全迷路了,不胜感激。

我插入了输入:

5 3 2 
1.2 3.4 0.1

2 次才崩溃。

代码如下:

int main()

    double* pdata;
    int n,d,k;
    scanf("%d %d %d",&n,&d,&k );
    SPPoint*  parr [n];
    for(int i=0; i<n; i++)
    
        double darr [d];
        for(int j = 0; j < d-1; j++)
        
            scanf(" %lf", &darr[j]);
        
        scanf(" %lf", &darr[d-1]);
    pdata = darr;
    parr[i] = spPointCreate(pdata, d, i); 
    

这是 spPointCreate 函数的代码:

struct sp_point_t
double* data;
int dim;
int index;
;

SPPoint* spPointCreate(double* data, int dim, int index)
SPPoint* point = malloc(sizeof(SPPoint*));
if(point == NULL)

    return NULL;

point->data = (double*) malloc(sizeof(data));
for( int i=0 ; i<dim ; i++)

    point->data[i] = data[i];

point->dim = dim;
point->index = index;
return point;

【问题讨论】:

分配了错误的大小。 SPPoint* point = malloc(sizeof(SPPoint*)); --> SPPoint* point = malloc(sizeof *point); 同样适用于point-&gt;data = malloc(sizeof *(point-&gt;data)); 非常感谢,现在似乎可以工作了! 其他问题也存在。 【参考方案1】:

SPPoint* point = malloc(sizeof(SPPoint*));

应该是:struct SPPoint* point = malloc(sizeof(*point));

point-&gt;data = (double*) malloc(sizeof(data));

应该是point-&gt;data = malloc(dim * sizeof(*point-&gt;data)); 因为你想为你的观点分配dim doubles。

【讨论】:

修复了第一个。关于第二个,给函数的数据数组的大小是dim。 不允许我编辑:修复了第一个。关于第二个,给函数的数据数组的大小是暗淡的。我认为 point->data = malloc(dim * sizeof(double));你在想什么?感谢您的回答 @Bar 是的,就是这样。你必须分配dim doubles @Bar 请注意,即使给定数据数组的大小为dimsizeof 函数在函数内部也无法知道它,因为它只是作为指针给出。 我明白了,所以你的意思是 sizeof 只是给了我双倍的大小【参考方案2】:

代码在 2 个地方分配错误

// Bad
SPPoint* spPointCreate(double* data, int dim, int index)
  SPPoint* point = malloc(sizeof(SPPoint*));  // allocate the size of a pointer
  ...
  point->data = (double*) malloc(sizeof(data)); // allocate the size of a pointer

而是避免错误编码类型并分配给取消引用变量的大小。

还需要分配N对象。

SPPoint* spPointCreate(double* data, int dim, int index)
  size_t N = 1;
  SPPoint* point = malloc(sizeof *point * N);// allocate the size of `*point` * N

  ...
  assert(dim >= 0);
  N = dim;
  point->data = malloc(sizeof *(point->data) * N);

顺便说一句,不需要转换malloc() 的结果。

第二次分配将受益于NULL 检查。更复杂的是,dim 可能是 0,在这种情况下,NULLmalloc() 返回是可以的。

  N = dim;
  point->data = malloc(sizeof *(point->data) * N);
  if (point->data == NULL && N > 0) 
    free(point);
    return NULL;
  

【讨论】:

以上是关于c上的代码崩溃,很可能与malloc有关?的主要内容,如果未能解决你的问题,请参考以下文章

使 malloc() 返回 NULL 而不是使程序崩溃?

malloc背后的调用机制-malloc内存分配过程详解

动态内存分配

malloc动态创建二维数组(C语言)

说说new 和 malloc()

Linux 上的崩溃分析