c语言如何复制数组,如何在C中使用memcpy()将数组复制到数组

我正在尝试从另一个数组a复制一个数组(temp)。

但我有没有发生。

Fig-1

int main()

{

typedef int arr_1[3];

arr_1 arr[4];

arr_1 *temp;

arr_1 a[3] = {1, 2, 3};

memset(&temp, 0, sizeof(temp));

memcpy(temp, a, sizeof(temp));

}

但是当我尝试使用下面的简单程序时,

Fig-2

main()

{

int abc[3], def[3];

def[3] = {1, 2, 3};

memcpy(abc, def, sizeof(abc));

}

上面的代码(fig-2)对我来说确实很好。

但是Fig-1对我不起作用。 两者完全一样。

但是为什么Fig-1无法正常工作?

sizeof(temp)是指针(指向int[3])的大小。

@All:强尼助记符技巧为我工作。 我只是用temp = (arr_1*)malloc(sizeof(arr_1));代替了memset。 它为我工作

因为temp不是数组,所以它是一个指针,因此sizeof(temp)绝对与数组没有关系。

您想要将memcpy更改为使用sizeof(a)。您还需要在复制temp之前为其赋予一个合理的值,否则该程序将具有未定义的行为。

@ AlokSave:约翰尼助记符提示为我工作。 我只是用temp = (arr_1*)malloc(sizeof(arr_1));替换了memset。 它为我工作

例如,您必须为temp和malloc()分配内存。现在,它只是一个未初始化的指针。

作为先前答案的摘要:

您应该为大小为sizeof(a)的tmp分配内存。然后大小为sizeof(a)的memcpy

arr_1 a[3] = {1, 2, 3};

arr_1 *temp = malloc(sizeof(a));

memcpy(temp, a, sizeof(a));

并且当temp在程序中使用free(temp);变得无用时,不要忘记释放它

我知道,我来晚了。但是当我阅读之前的答案时,我虽然"您不需要所有这些变量"

与您的简单示例:

int abc[3], def[3]; //abs is destination and def is source

def[3] = {1, 2, 3};

memcpy(abc, def, 3*sizeof(int)); //you can do sizeof(int) as you have here an array of int.

但是最好使用变量" const int array_size = 3"或" #define ARRAY_SIZE 3"来定义数组大小。然后,您只需将" 3"替换为" ARRAY_SIZE",即可完成相同的工作并避免尺寸错误。

对于您的实际问题,您可以执行以下操作:

#define ARRAY_SIZE 3

typedef int arr_1[ARRAY_SIZE];

arr_1 arr[ARRAY_SIZE+1];//it is useless here

arr_1 *temp = (arr_1 *) malloc(sizeof(arr_1)); //it is your destination, but you have a pointer of array

arr_1 a[ARRAY_SIZE] = {1, 2, 3};//it is your source

//by doing sizeof((*temp)[0])

//you do not care about the type of you array pointer

//you are sure to take the good size --> it fills your array with 0

memset((*temp), 0, (ARRAY_SIZE+1)*sizeof((*temp)[0]));

//same logic

//but you destination is (*temp) because you have a pointer of array

//it means that your array arr and a have the same type

memcpy((*temp), a, ARRAY_SIZE * sizeof(a[0]));

//by the way, the las cell of arr is still 0

//and a pointer is close to an array. If you do"tmp = a;" it works.

//but it is not a copy, you just give the a's reference to tmp

您还可以考虑一个辅助函数。

请参见RenéScharfe(rscharfe)的commit 45ccef8,commit 60566cb(2016年9月25日)。

(由Junio C Hamano合并-gitster-在commit b1f0a85中,2016年10月3日)

它使用COPY_ARRAY(一种安全且方便的辅助程序,用于复制阵列),

补充ALLOC_ARRAY和REALLOC_ARRAY。

因此,您可以使用COPY_ARRAY(temp, a, 1);代替memcpy(temp, a, sizeof(a));

Users just specify source, destination and the number of elements; the size of an element is inferred automatically.

It checks if the multiplication of size and element count overflows.

The inferred size is passed first to st_mult, which allows the division

there to be done at compilation time.

As a basic type safety check it makes sure the sizes of source and

destination elements are the same. That's evaluated at compilation time

as well.

COPY_ARRAY is safe to use with NULL as source pointer iff 0 elements are

to be copied.

That convention is used in some cases for initializing arrays.

Raw memcpy(3) does not support it -- compilers are allowed to

assume that only valid pointers are passed to it and can optimize away

NULL checks after such a call.

#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \\

BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))

static inline void copy_array(void *dst, const void *src, size_t n, size_t size)

{

if (n)

memcpy(dst, src, st_mult(size, n));

}

它使用声明了构建时相关性的宏BUILD_ASSERT_OR_ZERO作为表达式(@cond是必须为true的编译时条件)。

如果条件不成立或编译器无法评估该条件,则编译将失败。

#define BUILD_ASSERT_OR_ZERO(cond) \\

(sizeof(char [1 - 2*!(cond)]) - 1)

例:

#define foo_to_char(foo)                \\

((char *)(foo)                     \\

+ BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))

内联函数st_mult在提交320d0b4中引入

static inline size_t st_mult(size_t a, size_t b)

{

if (unsigned_mult_overflows(a, b))

die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,

(uintmax_t)a, (uintmax_t)b);

return a * b;

}

st_mult是用于检测size_t溢出的部分助手功能,其中包括unsigned_mult_overflows

Performing computations on size_t variables that we feed to xmalloc and friends can be dangerous, as an integer overflow can cause us to allocate a much smaller chunk than we realized.

We already have unsigned_add_overflows(), but let's add

unsigned_mult_overflows() to that

/*

* Returns true if the multiplication of"a" and"b" will

* overflow. The types of"a" and"b" must match and must be unsigned.

* Note that this macro evaluates"a" twice!

*/

#define unsigned_mult_overflows(a, b) \\

((a) && (b) > maximum_unsigned_value_of_type(a) / (a))

使用maximum_unsigned_value_of_type:helper检测未签名的溢出(来自提交1368f6)

The idiom (a + b < a) works fine for detecting that an unsigned integer has overflowed, but a more explicit

unsigned_add_overflows(a, b)

might be easier to read.

Define such a macro, expanding roughly to ((a) < UINT_MAX - (b)).

Because the expansion uses each argument only once outside of sizeof()

expressions, it is safe to use with arguments that have side effects.

#define bitsizeof(x) (CHAR_BIT * sizeof(x))

#define maximum_unsigned_value_of_type(a) \\

(UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))

其中CHAR_BIT是char中的位数(取决于体系结构)

您可以看到Git 2.23(2019年第三季度)的示例

请参见RenéScharfe(rscharfe)的commit 921d49b和177fbab(2019年6月15日)。

(由Junio C Hamano合并-gitster-在commit e8d2590中,2019年7月9日)

use COPY_ARRAY for copying arrays

Convert calls of memcpy(3) to use COPY_ARRAY, which shortens and

simplifies the code a bit.