我正在尝试从另一个数组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.