【问题标题】:Cant add more than 1 value to a dynamically created array in C不能向 C 中动态创建的数组添加超过 1 个值
【发布时间】:2017-04-04 14:06:05
【问题描述】:

我正在尝试在 C 中创建一个动态增加的数组,但由于某种原因,除了数组的第一个元素之外,我无法将值分配给任何东西。代码运行时,temp的值一直在变化,而val的内容只是一个地址和列表中第一个float的值。有任何想法吗?提前致谢!

//Initialise variables.
char buf[20]={0};
float temp=0;
int i=0;

//Create the initial array.
size_t size = sizeof(float)*10;
float* val = malloc(size);
if (val == NULL) {
    fprintf(stderr, "Initial malloc failed\n");
    exit(1);
}

//Open the file (a list of floats).
FILE *file;
file = fopen("/Users/cc756/Dropbox/C_ECG_PROJECT/ECG_Project/ECG_Project/dataStream", "r");

if (!file){
    printf("Coulding find file.\n");
    exit(1);
}

//Save the contents of the list to a float array.
while (fgets(buf,20, file)!=NULL){
    temp = atof(buf);
    if (temp != 0){
        val[i] = temp;
        i++;
        if(i==size){
            size *= 2;
            float* val_temp = realloc(val,size);
            if(val_temp == NULL){
                printf("Realloc failed.\n");
            }
            else{
                val = val_temp;
            }
        }
    }
}

【问题讨论】:

  • 你还没有在我能看到的任何地方初始化i...
  • 请阅读如何创建minimal reproducible example。您的代码不是minimal,因为您可以删除所有文件操作并通过简单循环演示问题。它也不是完整的,因为如果有人试图按原样编译它,它会抛出编译错误。
  • @ChrisCollins:你如何确定val[2]val[3] 没有被分配?调试器? printf?
  • @ChrisCollins:我对xcode 不太熟悉。记住val 是一个指针,而不是一个数组——也许你需要在xcode 中设置一些东西来查看val 之后的元素。还可以尝试使用printf 打印出您的数组元素。
  • 您的代码以及 Vlad 在其答案中提出的修复,运行良好。您的问题出在调试器上。添加我评论的循环,您会看到前 5 个位置的正确值

标签: c arrays memory malloc dynamic-arrays


【解决方案1】:

我想你是说

if ( i == size / sizeof( float ) ){

也是循环的逻辑

while (fgets(buf,20, file)!=NULL){
    temp = atof(buf);
    if (temp != 0){
        val[i] = temp;
        i++;
        if(i==size){
            size *= 2;
            float* val_temp = realloc(val,size);
            if(val_temp == NULL){
                printf("Realloc failed.\n");
            }
            else{
                val = val_temp;
            }
        }
    }
}

如果val_temp 将被分配NULL 是错误的,因为i 增加了并且在循环的下一次迭代中此语句

val[i] = temp;

导致未定义的行为。

【讨论】:

    【解决方案2】:

    所以,有几件事......

    如果您使用size 仅跟踪数组中元素的个数,而不是数组的字节大小,那么生活会简单得多。相信我。

    size_t size = 10;
    float *val = malloc( size * sizeof *val );
    

    另外,在您确定 realloc 调用成功之前不要更新 size 的值:

    if ( i == size )
    {
      float *val_temp = realloc( val, (size * 2) * sizeof *val );
      if ( val_temp )
      {
        size *= 2;
        val = val_temp;
      }
      else
      {
        // handle realloc failure
      }
    }
    

    为什么?您可能会认为 realloc 失败不是致命的,并返回您目前所读到的内容 - 在这种情况下,您希望 size 准确反映您所拥有的内容。

    至于解决您当前的问题,我建议添加一些调试printf 语句:

    while( ... )
    {
      ...
      fprintf( stderr, "i = %d\n", i );
      fprintf( stderr, "size = %zu\n", size );
      fprintf( stderr, "val = %p\n", (void *) val );
      fprintf( stderr, "val[%d] = %f\n\n", i, val[i] ); 
      ...
    }
    

    这样你就可以准确地看到你在循环的每次迭代中都有什么。

    【讨论】:

      猜你喜欢
      • 2014-05-23
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多