追加函数在调整大小的数组中不起作用

Append function not working in resized array

我正在构建一个数组,当它完全填满时会增加其大小。

情况是,用户调用 append 的值为 5,但数组(有 4 个槽)已满。我的程序调用我的 resize 函数,该函数将数组变成 8 个槽,保留 4 个旧值。

调整大小的实现工作正常,但它附加新值的部分,指定的插槽继续为空。像这样:

初始数组:
[1, 2, 3, 4]
调整大小并追加后的数组:
[1, 2, 3, 4, -1, -1, -1, -1]
预期结果:
[1, 2, 3, 4, 5, -1, -1, -1]
#define EMPTY -1
size_t capacity = 4;
int size = 0;

int main(void)
{
    int *arr = malloc(capacity * sizeof(int));
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
    arr[3] = 4;
    size = 4;

    appendInTheEnd(arr, 5, &arr);
    for (int i = 0; i < capacity; i++)
    {
        printf("%d ", arr[i]);
    }
}


void appendInTheEnd(int *arr, int value, int **array)
{
    if (size == capacity)
    {
        resizeArray(array, capacity);
        capacity *= 2;
        arr[size] = value;
        size++;
    }
}

void resizeArray(int **arr, size_t capacity)
{
    int *newArr = malloc(2 * capacity * sizeof(int));
    for (int i = capacity; i < 2 * capacity; i++)
    {
        newArr[i] = EMPTY;
    }
    memcpy(newArr, *arr, capacity * sizeof(int));
    memset(newArr + capacity, EMPTY, capacity);
    free(*arr);
    *arr = newArr;
}

appendInTheEnd() 什么都不做,除非 size == capacity。不要同时传入 arr 和数组。你只需要**arr。这是解决问题的最小更改(请参阅@0___________ 的回答以获得更大的步骤):

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

#define EMPTY -1
size_t capacity = 4;
int size = 0;

void resizeArray(int **arr, size_t capacity) {
    int *newArr = malloc(2 * capacity * sizeof(int));
    for (int i = capacity; i < 2 * capacity; i++)
    {
        newArr[i] = EMPTY;
    }
    memcpy(newArr, *arr, capacity * sizeof(int));
    memset(newArr + capacity, EMPTY, capacity * sizeof(int));
    free(*arr);
    *arr = newArr;
}

void appendInTheEnd(int **arr, int value) {
    if(size == capacity) {
        resizeArray(arr, capacity);
        capacity *= 2;
    }
    (*arr)[size++] = value;
}


int main(void) {
    int *arr = malloc(capacity * sizeof(int));
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
    arr[3] = 4;
    size = 4;

    appendInTheEnd(&arr, 5);
    for (int i = 0; i < capacity; i++) {
        printf("%d ", arr[i]);
    }
}

它会打印:

1 2 3 4 5 -1 -1 -1

我会更改打印循环以迭代直到大小而不是容量。保留值 >= 大小未初始化是完全可以的(不需要 resizeArray() 中的 memset;请注意,在 memset 中它应该是 capacity * sizeof(int) 而不仅仅是 capacity;我有一个之前的答案有错误,因为已修复),

顺便说一句,你的程序的下一步是创建一个结构来保存你的状态,所以它不是全局值:

struct int_array {
   int *data;
   size_t size;
   size_t capacity;
};

然后你写了一个 int_array_init() 函数来初始化你的结构,你改变了 resizeArray()appendInTheEnd 的签名以获取指向 struct *int_array; 的指针以及任何东西否则需要信息。然后将函数重命名为结构的前缀是个好主意,因此:

appendInTheEnd() 重命名为 int_array_append()
resizeArray() 重命名为 int_array_resize()

我会这样做:


typedef struct
{
    size_t size; 
    int data[];
} int_arr_type;


int_arr_type *append(int_arr_type *arr, int val)
{
    size_t new_size = arr ? arr -> size + 1 : 1;
    int_arr_type *new_arr = realloc(arr, sizeof(*new_arr) + new_size * sizeof(new_arr -> data[0]));

    if(new_arr)
    {
        new_arr -> data[new_size - 1] = val;
        new_arr -> size = new_size;
    }
    return new_arr;
}


int main(void)
{
    int_arr_type *a = NULL;

    a = append(a, 1);
    a = append(a, 2);
    a = append(a, 3);
    a = append(a, 4);
    a = append(a, 5);
    a = append(a, 6);

    for(size_t index = 0; index < a -> size; index++)
    {
        printf("a[%zu]=%d\n", index, a -> data[index]);
    }
}

https://godbolt.org/z/YT6hdnMd3