How to create an array without declaring the size in C?

六眼飞鱼酱① 提交于 2020-06-22 09:10:26

问题


I'm pretty new to new C and I wasn't able to find anything related to this (maybe because I'm not really sure what I'm looking for).

I'm trying to create a int and a float array without a size (it might be 0 or it might increment while the user use the program).

I was trying to do the follow:

int bills[];

float totalAmount[];

I can't assign a max size because I'm printing each array with a for loop (If I assign a size of 99 I'll print 99 lines, and I don't want that).

I'm pretty sure that this is possible but I don't know how.

Thanks!


回答1:


C does not support arrays with a dynamic number of elements. The number of elements of an array must be determined either at compile time or since C99 can be evaluated at runtime at the point of creation. Once the array is created, its size is fixed and cannot be changed. There are a few cases where the size is not explicitly specified between the [], either in array definitions or in array declarations.

You can define an array without an explicit size for the leftmost dimension if you provide an initializer. The compiler will infer the size from the initializer:

int a[] = { 1, 2, 3 };              // equivalent to int a[3] = { 1, 2, 3 };
int m[][2] = {{ 1, 2 }, { 3, 4 }};  // equivalent to int m[2][2] = {{ 1, 2 }, { 3, 4 }};
char s[] = "Hello world\n";         // equivalent to char s[13] = "Hello world\n";

Note how the compiler adds the implicit null terminator in the string case.

You can declare an array without a size specifier for the leftmost dimension in multiples cases:

  • as a global variable with extern class storage (the array is defined elsewhere),
  • as a function parameter: int main(int argc, char *argv[]). In this case the size specified for the leftmost dimension is ignored anyway.
  • as the last member of a struct. This is a C99 extension called a flexible array.

The compiler has no information on the actual size of these arrays. The programmer with use some other information to determine the length, either from a separate variable or from the array contents.

In the case of a function argument, the array is passed as a pointer and even if the number of elements is specified, sizeof(argv) evaluates to the size of a pointer.




回答2:


You could use a combination of malloc() (or calloc()), realloc() and free() to achieve this.

Memory can be allocated as blocks of a fixed size rather than reallocating memory for each number to be stored.

Let's define a macro (or a const if you like) BLOCK_SIZE.

#define BLOCK_SIZE 10

First declare a pointer of appropriate type and allocate the first block.

Note that malloc() as well as realloc() return NULL if some error occurred due to reasons like insufficient memory.

int *ptr=malloc(sizeof(int)*BLOCK_SIZE);    
if(ptr==NULL)
{
    perror("some error");
    return 1;
}

Now declare a variable to store the maximum possible index as per the currently allocated memory (to avoid illegal memory access).

int max_index = BLOCK_SIZE-1;

Now use a loop.

for(int i=0; ; ++i)
{
    if(i > max_index)
    {
        ptr=realloc(ptr, (max_index+1 + BLOCK_SIZE)*sizeof(int));
        if(ptr == NULL)
        {
            perror("insufficient memory!");
            break;
        }
        printf("\nRealloced!");
        max_index += BLOCK_SIZE;
    }
    scanf("%d", &ptr[i]);
    printf("\n%d: %d", i, ptr[i]);
}

In each iteration, we check if i is greater than max_index. If it is, another block is allocated using realloc() before reading the value.

Don't forget to deallocate the memory once you are done using it.

free(ptr);

Also, as discussed in this post, malloc() is effectively the same as realloc() with the latter's first argument NULL.

And in the code you posted, there's no need to explicitly cast the return value of calloc() as what's returned is a void pointer which would implicitly be converted to the target pointer type.

See this and this.




回答3:


You don't declare an array without a size, instead you declare a pointer to a number of records.

so, if you wanted to do

int bills[];

The proper way to do this in C is

int* bills;

And you will have to allocate the size at some point in time and initialzie the array.

bills = (int*)malloc(sizeof(int)*items);

The same goes for arrays of other data types. If you don't know the size of the array until runtime, you should use pointers to memory that is allocated to the correct size at runtime.



来源:https://stackoverflow.com/questions/50083744/how-to-create-an-array-without-declaring-the-size-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!