c 中的动态可扩展数组

问题描述 投票:0回答:1

我想在用户使用下面的代码输入值时动态扩展数组。

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

int main(){
    int *number=(int *)malloc(sizeof(int)),i=0,*new_ptr;
    printf("Enter a number to store it or -1 to finish the storage\n");
    scanf("%d",number);
    while(*(number+i)!=-1){
        printf("Enter a number to store it or -1 to finish the storage:\n");
        number=(int *)realloc(number,sizeof(number)+sizeof(int));
        i++;
        scanf("%d",number+i);
    };
    for(int j=0;j<i;j++){
        printf("%d ",number[j]);
    };
    return 0;
}

它给出了这个输出

Enter a number to store it or -1 to finish the storage
1
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
7
Enter a number to store it or -1 to finish the storage:
8
Enter a number to store it or -1 to finish the storage:
9
Enter a number to store it or -1 to finish the storage:
0
Enter a number to store it or -1 to finish the storage:
-1
1 2 3 4 5 6 7 8 540155953 540287027

仅当用户输入的数量大于 8 时才会出现垃圾文件值。为什么会出现这种情况以及如何修复?

c dynamic-memory-allocation
1个回答
0
投票

原始代码存在一些小问题。由于原始代码调用了未定义的行为,因此打印了垃圾值。 具体来说,realloc() 没有在旧逻辑中分配足够的空间。 realloc() 需要知道新的总空间

原始代码始终是 realloc()ing sizeof(number)+sizeof(int)...,转换为 sizeof(int *) + sizeof(int)。

该组合会产生一个不会增长的常数。这可能至少部分解释了为什么在阵列实际使用之前你可以获得良好的性能 需要比 sizeof(int *) + sizeof(int) 更多的空间。新代码通过更新分配大小逻辑修复了这个问题。

其他添加/更新:

  • 我们检查 scanf() 的返回(最佳实践)
  • 我们在将 realloc() 应用于我们的数字指针之前检查它的返回,这样我们就不会丢失数字指针引用。
  • 我们不会将 realloc() 返回到 (int *),这不是必需的
  • 评论中记录了其他改进。
  • 此代码是社区提出的几个重要观点以及我自己的一些独特观点的综合和体现。请欣赏:
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
        int *number=malloc(sizeof(int)), *temp, i=0,j, sres,scap;
      
        /* The do / while() loop design eliminates redundancy of the 
        ** scanf() prompt and fetch.  We prompt user and scan() 
        ** in a single code block. */
        do {
            printf("Enter a number to store it or -1 to finish the storage:\n");
            /* Use a separate, new variable to capture the scanf() input */
            sres = scanf("%d", &scap); /* Added: always check the return of scanf()*/
            if(sres!=1)
            {
                /* scanf() problem.  Alert user and exit. */
                printf("scanf() error!\n");
                return 0;
            }
            /* New logic/sequence.  If the captured value is not -1, store and continue*/
            if(scap != -1)
            {
                number[i++] = scap;  /* Store input to array */
                /* Updated allocation size logic: (i+1) means current count + next input: */
                temp = realloc(number, (i+1)*sizeof(number)); 
                if(temp)
                {
                    /* Preserve number pointer.  Only assign new 
                    ** memory if allocation was successful*/
                    number = temp; 
                }
                else
                {
                    /* realloc() problem.  Alert user and exit. */
                    printf("Coule not allocate memory for next input!\n");
                    return 0;
                }
            }
        }while(scap != -1);  /* Condition modified to adapt to new logic*/

        for(j=0;j<i;j++)
        {
            printf("%d ",number[j]);
        }

        system("pause");
        return 0;
    }


Output:

Enter a number to store it or -1 to finish the storage:
1
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
7
Enter a number to store it or -1 to finish the storage:
6
Enter a number to store it or -1 to finish the storage:
5
Enter a number to store it or -1 to finish the storage:
4
Enter a number to store it or -1 to finish the storage:
3
Enter a number to store it or -1 to finish the storage:
2
Enter a number to store it or -1 to finish the storage:
1
Enter a number to store it or -1 to finish the storage:
-1
1 2 3 4 5 6 7 6 5 4 3 2 1 
© www.soinside.com 2019 - 2024. All rights reserved.