How to allocate and deallocate heap memory for 2D array?

前端 未结 6 1248
一向
一向 2020-12-06 01:04

I\'m used to PHP, but I\'m starting to learn C. I\'m trying to create a program that reads a file line by line and stores each line to an array.

So far I have a prog

6条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-06 01:37

    There's no standard resizable array type in C. You have to implement it yourself, or use a third-party library. Here's a simple bare-bones example:

    typedef struct int_array
    {
        int *array;
        size_t length;
        size_t capacity;
    } int_array;
    
    void int_array_init(int_array *array)
    {
        array->array = NULL;
        array->length = 0;
        array->capacity = 0;
    }
    
    void int_array_free(int_array *array)
    {
        free(array->array);
        array->array = NULL;
        array->length = 0;
        array->capacity = 0;
    }
    
    void int_array_push_back(int_array *array, int value)
    {
        if(array->length == array->capacity)
        {
            // Not enough space, reallocate.  Also, watch out for overflow.
            int new_capacity = array->capacity * 2;
            if(new_capacity > array->capacity && new_capacity < SIZE_T_MAX / sizeof(int))
            {
                int *new_array = realloc(array->array, new_capacity * sizeof(int));
                if(new_array != NULL)
                {
                   array->array = new_array;
                   array->capacity = new_capacity;
                }
                else
                    ; // Handle out-of-memory
            }
            else
                ; // Handle overflow error
        }
    
        // Now that we have space, add the value to the array
        array->array[array->length] = value;
        array->length++;
    }
    

    Use it like this:

    int_array a;
    int_array_init(&a);
    
    int i;
    for(i = 0; i < 10; i++)
        int_array_push_back(&a, i);
    for(i = 0; i < a.length; i++)
        printf("a[%d] = %d\n", i, a.array[i]);
    
    int_array_free(&a);
    

    Of course, this is only for an array of ints. Since C doesn't have templates, you'd have to either put all of this code in a macro for each different type of array (or use a different preprocessor such as GNU m4). Or, you could use a generic array container that either used void* pointers (requiring all array elements to be malloc'ed) or opaque memory blobs, which would require a cast with every element access and a memcpy for every element get/set.

    In any case, it's not pretty. Two-dimensional arrays are even uglier.

提交回复
热议问题