没有可以包含的元素数量的预定义限制的数组

时间:2018-12-13 12:45:09

标签: c

对于我的项目,我必须在堆栈中存储一个堆栈。我为此使用数组,但是不允许该数组具有预定义的限制。

我不确定如何在C中无限制地创建数组。下面的代码是我的最佳尝试,并产生错误消息“数组大小具有非整数类型”。任何帮助,将不胜感激。

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



 int main()
 {
    int *g = malloc(100 *sizeof(int));
    free(g);
    int array[g];


    printf("the array spot 0 is \n");
    scanf("&i\n", array[0]);

    printf("the array spot 1 is \n");
    scanf("&i\n", array[1]);

    printf("the array place 1 is %i and %i\n",array[0],array[1]);

    return 0;
 }

4 个答案:

答案 0 :(得分:1)

首先,让我告诉您,没有“没有限制” ,毕竟您受系统上的内存(物理或虚拟)限制。

也就是说,如果您想要一个没有预定义大小的数组,并且大小是在运行时确定的,则有两个选择:

  1. 您可以考虑使用VLA (Variable length array)。对此的内存分配取决于植入,例如,gcc在堆栈上分配VLA-因此您的大小受系统上堆栈大小的限制。

  2. 另一方面,如果您可以使用动态内存分配,则可以使用指针并使用malloc()realloc()来分配和调整分配的内存大小。指针将不会是数组(反之亦然),但除此之外,没有通用的原因使其不符合您的目的。

答案 1 :(得分:0)

您误解了malloc的操作

此行:

  int *g = malloc(100 *sizeof(int));

正在手动创建大小为100的数组

因此您可以使用

 g[0]   
 g[1]

访问数组中的元素

对于free部分:此方法销毁(释放)您的数组,因此,当您不再需要数组时(例如,在主体的末尾),必须调用它。

答案 2 :(得分:0)

考虑以下示例:

#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

typedef struct {
    size_t  num;    /* Number of ints in array */
    size_t  max;    /* Number of ints allocated for */
    int    *array;
} intarray;
#define  INTARRAY_INIT  { 0, 0, NULL }

/* Discard an intarray. */
void intarray_free(intarray *iarr)
{
    if (iarr) {
        free(iarr->array); /* Note: free(NULL) is safe to do. */
        iarr->num = 0;
        iarr->max = 0;
        iarr->array = NULL;
    }
}

/* Ensure there is room for at least 'more' additional ints in the intarray. */
void intarray_need(intarray *iarr, const size_t  more)
{
    int    *array;
    size_t  max;

    /* No intarray specified? */
    if (!iarr) {
        fprintf(stderr, "intarray_need(): iarr == NULL!\n");
        exit(EXIT_FAILURE);
    }

    /* Calculate size needed. */
    max = iarr->num + more;

    /* Array already large enough? */
    if (iarr->max >= max)
        return;

    /* Growth policy: increase allocated size,
       to avoid reallocating in too small chunks. */
    if (max < 8) {
        /* Always at least 8 ints. */
        max = 8;  
    } else
    if (max < 524288) {
        /* Grow by 50% up to 524288. */
        max = (3 * max) / 2;
    } else {
        /* Round up to next multiple of 262144, less 32. */
        max = (max | 262143) + 262145 - 32;
    }

    /* Allocate. */
    array = realloc(iarr->array, max * sizeof iarr->array[0]);
    if (!array) {
        fprintf(stderr, "intarray_need(): Out of memory; num == %zu, more == %zu, new max == %zu.\n",
                        iarr->num, more, max);
        exit(EXIT_FAILURE);
    }

    iarr->max   = max;
    iarr->array = array;
}

/* Add one int to the intarray. */
void intarray_add(intarray *iarr, const int val)
{
    /* We need room for at least one more int. */
    intarray_need(iarr, 1);

    /* Append. */
    iarr->array[iarr->num++] = val;
}

int main(void)
{
    intarray  data = INTARRAY_INIT;
    size_t    i;
    int       val;

    /* Parse ints from standard input. */
    while (scanf("%d", &val) == 1) {
        intarray_add(&data, val);
    }

    /* Why did the scan fail? */
    if (ferror(stdin)) {
        fprintf(stderr, "Error reading from standard input.\n");
        exit(EXIT_FAILURE);
    } else
    if (feof(stdin)) {
        printf("All input converted successfully.\n");
        /* Fall through */
    } else {
        fprintf(stderr, "Warning: Could not parse all standard input.\n");
        /* Fall through */
    }

    printf("Read %zu ints:\n", data.num);
    for (i = 0; i < data.num; i++)
        printf("%12d\n", data.array[i]);

    intarray_free(&data);

    return EXIT_SUCCESS;
}

intarray类型是一种结构类型,它包含成员maxnumarray。使用INTARRAY_INIT将其初始化为已知值。

intarray_free()函数丢弃一个整数数组。

intarray_more()函数很有趣。它确保为指定数量的附加int分配足够的内存。请注意,realloc(NULL, SIZE)等效于malloc(SIZE);因为该结构已正确初始化(INTARRAY_INIT),所以我们可以将其重新分配为所需的大小。

此处显示的调整大小策略只是一个示例,大致代表了我本人可能会使用的策略。它包含三个部分:最小分配大小,指数增长部分和线性增长部分。目的是,这种增长适用于小型和大型阵列,而没有巨大的缺点。真正大的线性增长部分(max = (max | 262143) + 262145 - 8;)是一种好奇,因为它使用简单的二进制运算将其取整为2 18 = 262144的下一个倍数减去8个整数:这个想法是允许C库分配一块2 18 的倍数的块,包括其自身的开销。潜在的希望是,OS可以比其他大小更有效地做到这一点(具体来说,以2的大数的倍数进行分配)。把它当作现实生活中可能看到的例子;不是你应该做的。

虽然intarray_add()一次只添加一个int,但您可以轻松编写另一个函数,一次添加多个int。只需记住先调用intarray_need(),以确保有足够的内存分配给新整数。

如果您编译并运行该程序,它将从标准输入中读取整数,直到您提供非整数输入,或者遇到输入结尾(例如,从文件重定向输入)。

例如,如果您以program.exe < file.txt./program < file.txt的形式运行程序,且其中file包含

1 2
3 4 5
-6 -7
-8
9

那么输出是

All input converted successfully.
Read 9 ints:
       1
       2
       3
       4
       5
      -6
      -7
      -8
       9

唯一的限制是该程序可用的内存量。

程序中还剩下一个bug:在max中计算intarray_need()时可能溢出,并且要重新分配的字节数(realloc()的第二个参数)。可以检查这些参数,因为所有参数的类型均为size_t,这是一些无符号整数类型。在C语言中,无符号整数类型使用取模算术(也就是说,就像所有计算都是取模 UINT_MAX + 1一样)。

答案 3 :(得分:-1)

您可以初始化一个大小,然后在空间不足时将大小翻倍,并将所有元素转储到新创建的数组中。

本文讨论了如何在C语言中实现 https://codereview.stackexchange.com/questions/64423/implementing-an-arraylist