6

我正在尝试(temp)从另一个数组复制一个数组a。但我有它没有发生。

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不工作?

4

5 回答 5

9

因为temp它不是一个数组,它是一个指针,因此sizeof(temp)与数组完全没有关系。

您想更改memcpy使用sizeof(a). 您还需要temp在复制之前给出一个合理的值,否则程序会出现未定义的行为。

于 2013-03-28T15:05:34.727 回答
5

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

于 2013-03-28T15:08:04.040 回答
3

我知道,我迟到了。但是当我阅读以前的答案时,我认为“你不需要所有这些变量”

使用您的简单示例:

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
于 2018-08-02T15:12:41.710 回答
2

作为先前答案的摘要:

tmp您应该为size =分配内存sizeof(a)。然后memcpy用 size = sizeof(a)

arr_1 a[3] = {1, 2, 3};
arr_1 *temp = malloc(sizeof(a));
memcpy(temp, a, sizeof(a));

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

于 2013-03-28T15:31:37.427 回答
1

你也可以考虑一个辅助函数。
请参阅René Scharfe ( )的提交 45ccef8提交 60566cb(2016 年 9 月 25 日) 。(由Junio C Hamano 合并 -- --提交 b1f0a85中,2016 年 10 月 3 日)rscharfe
gitster

它使用COPY_ARRAY, 一个安全方便的助手来复制数组,补充ALLOC_ARRAYREALLOC_ARRAY.

因此memcpy(temp, a, sizeof(a));,您将使用COPY_ARRAY(temp, a, 1);

用户只需指定来源、目的地和元素数量;元素的大小是自动推断的。

它检查大小和元素计数的乘积是否溢出。
推断的大小首先传递给st_mult,这允许在编译时进行除法。

作为基本类型安全检查,它确保源元素和目标元素的大小相同。这也在编译时进行了评估。

COPY_ARRAYNULL如果要复制 0 个元素,则可以安全地用作源指针。
该约定在某些情况下用于初始化数组。
Rawmemcpy(3)不支持它——编译器被允许假设只有有效的指针被传递给它,并且可以 NULL在这样的调用之后优化掉检查。

#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编译时条件必须为真)。
如果条件不成立或编译器无法评估,则编译将失败。

#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_multcommit 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

size_t对我们提供给和朋友的变量执行计算xmalloc可能很危险,因为整数溢出会导致我们分配的块比我们意识到的要小得多。

我们已经有了unsigned_add_overflows(),但让我们补充 unsigned_mult_overflows()一下

/*
 * 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: 检测无符号溢出的助手 (来自提交 1368f6

该成语(a + b < a)可以很好地检测无符号整数是否溢出,但更明确

unsigned_add_overflows(a, b)

可能更容易阅读。

定义这样一个宏,大致扩展为((a) < UINT_MAX - (b)).
因为展开式只在表达式之外使用每个参数一次sizeof() ,所以与具有副作用的参数一起使用是安全的。

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

#define maximum_unsigned_value_of_type(a) \
(UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))

是 char中CHAR_BIT的位数(取决于架构)


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

请参阅René Scharfe ( ) 的提交 921d49b提交 177fbab(2019 年 6 月 15 日(由Junio C Hamano 合并 -- --提交 e8d2590中,2019 年 7 月 9 日)rscharfe
gitster

用于COPY_ARRAY复制数组

将调用转换memcpy(3)为使用COPY_ARRAY,这会稍微缩短和简化代码。

于 2017-08-12T09:26:28.853 回答