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

Posted

技术标签:

【中文标题】附加函数在调整大小的数组中不起作用【英文标题】:Append function not working in resized array 【发布时间】:2021-11-19 04:32:58 【问题描述】:

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

情况是,用户调用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;


【问题讨论】:

main() 中,您设置了 1 到 4 的值,但在您的问题中您说初始数组是 0 到 4。建议您编辑问题以匹配代码。 你又救了我...谢谢 你为什么不用realloc 【参考方案1】:

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

我会更改打印循环以迭代直到大小而不是容量。将值 >= size 保留为未初始化是完全可以的(在 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()

【讨论】:

非常感谢!我会看看结构部分,但你的回答解决了我的问题。因为我的水平太低,我不能投票,但我很感激。【参考方案2】:

我会这样做:


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

【讨论】:

以上是关于附加函数在调整大小的数组中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

具有自动调整大小的 UICollectionViewCell 在 iOS 9 中不起作用,但在 iOS 10 中起作用

UICollectionViewListCell 的自定义子类中的自我调整大小在 iOS 14 中不起作用

非附加元素宽度在 Chrome 中不起作用

具有自动调整大小的多个文本区域在 ionic3 中不起作用

附加功能在复制的工作表中不起作用

UIImageView setFrame:在 UITableViewCell 中不起作用