C问题中的动态内存分配

C问题中的动态内存分配,c,C,我试图增加a的记忆,但realloc似乎什么都没做。在第四位,程序崩溃。似乎数字也被放入[0]中,即使计数器增加,也应该是[counter]。我知道我从[1]开始,因为当我完成输入时,我正在[0]中写入计数器本身 printf:Input vector的转换(输入结束时使用除点以外的任何非数字字符) 编辑: 非常感谢。你们的回答都很好 有没有办法找出分配了多少内存空间? 在后面的代码中,我用sizeof(a)/sizeof(float)检查该数组中的元素数量,现在我知道该数组是不正确的。幸运的是

我试图增加a的记忆,但realloc似乎什么都没做。在第四位,程序崩溃。似乎数字也被放入[0]中,即使计数器增加,也应该是[counter]。我知道我从[1]开始,因为当我完成输入时,我正在[0]中写入计数器本身

printf:Input vector的转换(输入结束时使用除点以外的任何非数字字符)

编辑: 非常感谢。你们的回答都很好

有没有办法找出分配了多少内存空间? 在后面的代码中,我用sizeof(a)/sizeof(float)检查该数组中的元素数量,现在我知道该数组是不正确的。幸运的是,我有一个存储在内存中的计数器,所以我知道我有多少元素,但如果我不存储这些信息,我怎么知道呢

a = realloc(a, (sizeof(a) + sizeof(float)));
sizeof(a)
sizeof(float)
都是常量(在大多数情况下,
sizeof(任意)
都是常量)。所以你总是要求同样的内存量

通常情况下,你需要的东西大致如下:

a = realloc(a, counter * sizeof(float));
但是

  • 您需要通过一个错误来检查这一点:也许您需要
    (计数器+1)
    ,而不是
    计数器
    ,等等
  • 永远不要使用
    a=realloc(a,…)
    。查看
    realloc
    如何报告错误(以及在发生错误时如何处理原始内存块)以了解原因
  • 另见

    sizeof(a)
    sizeof(float)
    都是常量(在大多数情况下,
    sizeof(任意)
    都是常量)。所以你总是要求同样的内存量

    通常情况下,你需要的东西大致如下:

    a = realloc(a, counter * sizeof(float));
    
    但是

  • 您需要通过一个错误来检查这一点:也许您需要
    (计数器+1)
    ,而不是
    计数器
    ,等等
  • 永远不要使用
    a=realloc(a,…)
    。查看
    realloc
    如何报告错误(以及在发生错误时如何处理原始内存块)以了解原因

  • 另请参见
    realloc
    不正确。您得到的是计算机上指针的大小,而不是到目前为止分配的空间的大小

    float *a = (float *) malloc(sizeof(float));
    /* .... */
    a = realloc(a, (sizeof(a) + sizeof(float)));
    
    因此,假设一个
    float*
    占用4个字节。您将始终分配
    4+sizeof(float)
    ,最终您将退出。您需要跟踪元素的数量,然后:

    a = realloc(a, sizeof(float) * (el_no + 1));
    
    当然,更好的形式是:

    a = realloc(a, sizeof(*a) * (el_no + 1));
    
    如果您以后决定更改
    a
    的类型,这样您就安全了

    编辑


    作为补充说明,为每个新元素调用
    realloc
    似乎是一笔不错的交易,但速度很慢。您应该采用类似“当空间用完时,我将使当前使用量翻倍”之类的策略或类似的策略。

    realloc不正确。您得到的是计算机上指针的大小,而不是到目前为止分配的空间的大小

    float *a = (float *) malloc(sizeof(float));
    /* .... */
    a = realloc(a, (sizeof(a) + sizeof(float)));
    
    因此,假设一个
    float*
    占用4个字节。您将始终分配
    4+sizeof(float)
    ,最终您将退出。您需要跟踪元素的数量,然后:

    a = realloc(a, sizeof(float) * (el_no + 1));
    
    当然,更好的形式是:

    a = realloc(a, sizeof(*a) * (el_no + 1));
    
    如果您以后决定更改
    a
    的类型,这样您就安全了

    编辑


    作为补充说明,为每个新元素调用
    realloc
    似乎是一笔不错的交易,但速度很慢。你应该采取“当我用完空间时,我会将当前使用量翻倍”之类的策略或类似的策略。

    不管你怎么想:

    if (sizeof(a) == sizeof(float)) {
          return NULL;
    }
    

    不管你怎么想:

    if (sizeof(a) == sizeof(float)) {
          return NULL;
    }
    
    简而言之,
    sizeof(a)
    不会做你认为它会做的事。
    a
    的类型是
    *float
    ,因此它的大小非常小。您需要跟踪数组的长度,并将其乘以
    sizeof(float)
    以获得当前大小。

    简言之
    sizeof(a)
    并没有达到您认为的效果。
    a
    的类型是
    *float
    ,因此它的大小非常小。您需要跟踪数组的长度,并将其乘以
    sizeof(float)
    以获得当前大小。

    执行以下操作时:

     float *a = (float *) malloc(sizeof(float));
    
     ...
     a = realloc(a, (sizeof(a) + sizeof(float)));
    
    “sizeof(a)”总是返回4(在32位机器上,8在64位机器上)。”尽管它的外观不是一种功能。这是一个算符,它给出了变量的大小。在本例中,“a”只是一个指针。sizeof不会给出a所指向的对象的大小

    您需要做的是保留一个长度变量,该变量跟踪malloc/realloc分配的块中的浮点数

      int N_floats = 0 ;
      float *a = (float *)malloc(0) ;
      /* add a float */
    
      a = (float *)realloc(a, (N_floats+1)*sizeof(float)) ;
      a[N_floats] = 1.0 ;
      N_floats += 1;
    
    当您这样做时:

     float *a = (float *) malloc(sizeof(float));
    
     ...
     a = realloc(a, (sizeof(a) + sizeof(float)));
    
    “sizeof(a)”总是返回4(在32位机器上,8在64位机器上)。”尽管它的外观不是一种功能。这是一个算符,它给出了变量的大小。在本例中,“a”只是一个指针。sizeof不会给出a所指向的对象的大小

    您需要做的是保留一个长度变量,该变量跟踪malloc/realloc分配的块中的浮点数

      int N_floats = 0 ;
      float *a = (float *)malloc(0) ;
      /* add a float */
    
      a = (float *)realloc(a, (N_floats+1)*sizeof(float)) ;
      a[N_floats] = 1.0 ;
      N_floats += 1;
    

    您得到的错误意味着您的堆段中存在缓冲区溢出。这是因为在第15行,您会:

    a = realloc(a, (sizeof(a) + sizeof(float)));
    
    sizeof是一个宏函数,它将在编译时确定,而不是在运行时。您应该使用计数器来计算新读取所需的大小。试着这样做:

    a = realloc(a, (sizeof(*a) * (counter + 1))); // +  one for the counter itself
    
    您还需要记住,在第21行,您将整数(计数器)强制转换为和浮点,这将导致计数器以负值换行并重新启动

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int value = 822222233;
        float flt = value;
    
        printf("equal: %s\nvalue = %d\nflt = %f\n(int)flt = %d", value == flt ? "true" : "false", value, flt, ((int)flt));
    
        exit(0);
    }
    

    如您所见,计数器将损坏:)

    您得到的错误意味着您的堆段中存在缓冲区溢出。这是因为在第15行,您会:

    a = realloc(a, (sizeof(a) + sizeof(float)));
    
    sizeof是一个宏函数,它将在编译时起决定作用,而不是在运行时使用计数器