首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >赋值指针vs memcpy/memmove

赋值指针vs memcpy/memmove
EN

Stack Overflow用户
提问于 2013-05-23 17:47:36
回答 5查看 1.9K关注 0票数 3

嗨,我有一个关于C指针(特别是void *)的问题。

我正在使用void *指针,这些指针指向作为Vector实现的单元的任意内存块。这些blob是在堆上分配的。

我的问题是为什么赋值

代码语言:javascript
复制
    void *dest = CVectorNth(cv, i);
    void *src = CVectorNth(cv, i-1);
    *(void **)dest = *(void **)src;

不工作时

代码语言:javascript
复制
    memmove(dest, src, elementSize);

确实行得通。

为什么我需要使用memmove?在我的头中,我将指针的值更改为src所指向的地址。

我知道memmove是正确的方法,但现在我甚至想不出一个理由

代码语言:javascript
复制
    dest = src;

不会起作用

EN

回答 5

Stack Overflow用户

发布于 2013-05-23 17:58:32

代码语言:javascript
复制
*(void **)dest = *(void **)src;

destsrc解释为指向void*的指针,并将sizeof(void *)字节从src指向的位置复制到dest指向的位置。

代码语言:javascript
复制
memmove(dest, src, elementSize);

elementSize字节从src指向的位置移动到dest指向的位置。如果可能是elementSize == sizeof(void *),如果受影响的区域不重叠,并且srcdest都适当对齐,则两者将具有相同的效果。如果destsrc中的任何一个没有正确对齐,第一个将调用未定义的行为(如果受影响的区域重叠,则至少有一个区域可能不会正确对齐)。

如果您有一个特定的Element类型,您只需要将destsrc转换为适当的类型。

代码语言:javascript
复制
*(Element *)dest = *(Element *)src;

以达到预期的效果。

票数 4
EN

Stack Overflow用户

发布于 2013-05-23 17:57:14

这是因为C语言遵循一种设计哲学,归根结底就是“你不会为你不需要的东西付费,你也不会得到你不想要的东西”。特别是,当您声明一个变量的类型为void*时,然后您请求一个可以指向任何内容的指针,而您得到的只是一个这样的指针;而不是指针+类型字段+所指向的对象的大小字段,因此编译器不知道您打算复制多少字节。

请注意,

代码语言:javascript
复制
dest = src;

确实起作用了,但它并不像你期望的那样。它将dest重新指定为指向与src相同的事物,这意味着您现在对同一事物有两个名称(可能是内存泄漏)。这可能非常有用(除了泄漏),但它是一个非常浅的副本。

至于

代码语言:javascript
复制
*(void **)dest = *(void **)src;

在大多数情况下,这是未定义的行为。当它工作时,它将src作为指向void*的指针,并将其赋值给dest指向的void*,所以它仍然是一个指针副本,尽管是间接的。

票数 1
EN

Stack Overflow用户

发布于 2013-05-23 17:56:57

有了两个指针,你可以这样做:

代码语言:javascript
复制
*(char*) dest = *(char*) src;
*(double*) dest = *(double*) src;
*(struct{char[50] a;}*) dest = *(struct{char[50] a;}*) src;

等同于:

代码语言:javascript
复制
memcpy(dest, src, sizeof(char));

但不幸的是,C中的指针并不知道其分配的大小。通过它的类型可以知道它的元素大小,但是任何数组的大小都是未知的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16710633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档