将标量和数组添加到 C 中的另一个数组

Prepend scalar and arrays to another array in C

我正在研究一组允许动态增长用户定义数组的 C 函数。在本网站上一些人的帮助下,我已经能够开发充当数组初始化的函数,以及另一个可以将标量附加到数组或将数组附加到数组的函数。我正在使用一个名为 Array 的结构,它充当数组 array、数组的活动长度 len、数组的总分配大小 size 的容器,和每个索引的内存 elem.

第一个函数initialize_array分配内存并初始化数组,函数init_arrayinitialize_array的包装器,预格式化一些信息和returns Array 数据类型。最后,我有一个函数 append_array,它可以采用标量或数组,并可以使用 memcp 方法将数组附加到 Array 结构中,该方法被转换为 char 到协助指针运算。我正在尝试使用 prepend_array 函数重新创建 append_array 函数,该函数将在第一个索引中添加 *items 中传递的标量或数组,并将其他索引推到左侧。我对如何执行此操作有点迷茫,任何建议都会有所帮助。

array.h

#ifndef ARRAY_H
#define ARRAY_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
    void *array; // Container for array
    size_t len;  // Active length of array
    size_t size; // Size of allocated memory
    int elem;    // Memory consumption per element
} Array;

void initiate_array(Array *array, size_t num_indices);
Array init_array(int size, size_t num_indices);
int append_array(Array *array, void *items, size_t count);
int prepend_array(Array *array, void *items, size_t count);

#endif /* ARRAY_H */

array.c

#include "array.h"

void initiate_array(Array *array, size_t num_indices) {
    void *pointer;

    pointer = malloc(num_indices * array->elem);

    if (pointer == NULL) {
        printf("Unable to allocate memory, exiting.\n");
        free(pointer);
        exit(0);
    }
    else {
        array->array = pointer;
        array->len = 0;
        array->size = num_indices;
    }
}

Array init_array(int size, size_t num_indices) {
    Array array;
    array.elem = size;
    initiate_array(&array, num_indices);
    return array;
}

int append_array(Array *array, void *items, size_t count) {
    if (array->len + count > array->size) {
        size_t size = (array->len + count) * 2;
        void *pointer = realloc(array->array, size * array->elem);
        if (pointer == NULL) {
            return 0;
        }
        array->array = pointer;
        array->size = size;
    }
    memcpy((char *)array->array + array->len * array->elem, items, count * array->elem);
    array->len += count;
    return 1;
}

int prepend_array(Array *array, void *items, size_t count) {
    if (array->len + count > array->size) {
        size_t size = (array->len + count) * 2;
        void *pointer = realloc(array->array, size * array->elem);
        if (pointer == NULL) {
            return 0;
        }
        array->array = pointer;
        array->size = size;
    }
    // Not sure how to handle this with memcp like was used for append_array
    array->len += count;
    return 1;
}

main.c

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

int main(int argc, char** argv)
{
    int i, j;
    float ii = 0.0;
    size_t indices = 20;
    Array float_test = init_array(sizeof(float), indices);
    Array int_test = init_array(sizeof(int), indices);
    // Populate both arrays
    for (i = 0; i < 30; i++) {
        ii += 1.1;
        append_array(&int_test, &i, 1);
        append_array(&float_test, &ii, 1);
    }

    int a[3] = {10, 9, 8};
    prepend_array(&int_test, a, 3);
    // Print int array values
    for (i = 0; i < int_test.len; i++)
    {
        printf("Value: %d Size:%zu \n",((int *) int_test.array)[i], int_test.len);
    }
    return (EXIT_SUCCESS);
}

要将元素添加到数组中,分配额外内存后,您首先需要移动 现有元素。

destinationsource 内存有重叠的可能性时,我们使用 memmove 来安全地移动我们的数据1.

移动现有元素后,我们将新元素复制到位。

可视化:

A is [11, 22, 33, 44, 55]
V is [99, 88, 77]

resize(A):      [11, 22, 33, 44, 55, __, __, __]
move(A + 3, A): [__, __, __, 11, 22, 33, 44, 55]
copy(A, V):     [99, 88, 77, 11, 22, 33, 44, 55]

根据您的代码,这看起来像:

memmove(
    ((char *) array->array) + count * array->elem,
    array->array,
    array->len * array->elem);

memcpy(array->array, items, count * array->elem);

1. memcpy to copy to and from overlapping memory is Undefined Behavior 的使用,以及许多错误的来源。