将标量和数组添加到 C 中的另一个数组
Prepend scalar and arrays to another array in C
我正在研究一组允许动态增长用户定义数组的 C 函数。在本网站上一些人的帮助下,我已经能够开发充当数组初始化的函数,以及另一个可以将标量附加到数组或将数组附加到数组的函数。我正在使用一个名为 Array
的结构,它充当数组 array
、数组的活动长度 len
、数组的总分配大小 size
的容器,和每个索引的内存 elem
.
第一个函数initialize_array
分配内存并初始化数组,函数init_array
是initialize_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);
}
要将元素添加到数组中,分配额外内存后,您首先需要移动 现有元素。
当 destination 和 source 内存有重叠的可能性时,我们使用 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 的使用,以及许多错误的来源。
我正在研究一组允许动态增长用户定义数组的 C 函数。在本网站上一些人的帮助下,我已经能够开发充当数组初始化的函数,以及另一个可以将标量附加到数组或将数组附加到数组的函数。我正在使用一个名为 Array
的结构,它充当数组 array
、数组的活动长度 len
、数组的总分配大小 size
的容器,和每个索引的内存 elem
.
第一个函数initialize_array
分配内存并初始化数组,函数init_array
是initialize_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);
}
要将元素添加到数组中,分配额外内存后,您首先需要移动 现有元素。
当 destination 和 source 内存有重叠的可能性时,我们使用 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 的使用,以及许多错误的来源。