【问题标题】:Values displayed after realloc are weirdrealloc 之后显示的值很奇怪
【发布时间】:2019-06-14 02:38:38
【问题描述】:

我打电话给malloc,然后我想使用realloc 将大小减半,当我显示重定位malloc 的值时,少数数字显示为0,这是正常的还是我搞砸了?

double main()
{
    double *test;
    int size = 10;
    int sizes;
    int i = 0;
    double value;
    test = (double*)malloc(size*sizeof(double));
    if(test == NULL)
    {
        printf("ERROR");
        return 0;
    }
    else
    {
        printf("\nInsert values : \n");
        for(i=0;i<=size;)
        {
            scanf("%lf",&*(test+i));
            if(*(test+i)==0.0)
            {
                break;
            }
            if(i>=size)
            {
                size=size+2;
                test = realloc(test, size*sizeof(double));
            }
            i++;
        }
    }
    sizes=size/2;
    test = realloc(test, sizes*sizeof(double));
    printf("\nSaved values : \n");
    for(i=0;i<size;i++)
    {
        printf("%lf\n",*(test+i));
    }

}

我想学习一些编码,所以请告诉我是否以及我做错了什么。

【问题讨论】:

  • 不需要在 C 中转换 malloc(),同样的原因 realloc() 不需要转换。
  • 这个i&lt;=size 看起来很可疑。
  • 我建议您停止对“数组”使用指针算术语法,而是使用例如test[i](而不是 *(test + i))。它将使代码更易于阅读(并且更少编写)。
  • 您最终将test 重新分配到sizes=size/2;,但随后循环到i=0;i&lt;size; 您是否有意这样做?
  • double main()胡?! main() 应该返回 int

标签: c malloc


【解决方案1】:

如果我很理解您在 EOF 或读取值为 0 时停止读取值,并且未记住 0,并且当读取完成时您希望将分配向量减小到最小大小,在这种情况下:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int size = 10;
    double *test = malloc(size*sizeof(double));

    if(test == NULL)
    {
        printf("ERROR");
        return 0;
    }
    else
    {
      int i = 0;
      double value;

      printf("\nInsert values : \n");
      while ((scanf("%lf",&value) == 1) && (value != 0))
      {
          if (i >= size) /* == is enough */
          {
            size += 2; /* I add 2 entries as you */
            test = realloc(test, size*sizeof(double));
          }
          test[i++] = value;
      }

      /* remove possible extra entry at the end */
      if (i != size)
          test = realloc(test, i*sizeof(double));

      size = i;

      printf("\nSaved values : \n");
      for(i=0 ;i<size; ++i)
      {
        printf("%lf\n",test[i]);
      }

      free(test);
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    这里有两个问题:

    1. 这个

      for(i=0;i<=size;) 
      

      做这个

        scanf("%lf",&*(test+i));
      

      在重新分配之前的最后一次迭代中扫描到内存超出已分配内存的一个元素。这样做会调用未定义的行为。从现在开始,任何事情都可能发生。

    2. 这两行

      sizes=size/2;
      test = realloc(test, sizes*sizeof(double));
      

      将有效内存缩小到其大小的一半,然后这个循环

      for(i=0;i<size;i++)
      {
        printf("%lf\n",*(test+i));
      }
      

      试图读出刚刚被缩小的后半部分的值。这一半的内存不再有效。尝试阅读它也会调用未定义的行为

    所以回答你的问题:

    或者我搞砸了

    是的,你做到了,即通过调用未定义的行为。不要那样做。

    【讨论】:

    • 所以我必须将sizes 更改为size,一切都应该没问题?
    • @przemo10371:您必须解决两个问题。在任何情况下都必须避免未定义的行为。
    猜你喜欢
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 2018-10-22
    相关资源
    最近更新 更多