[英]Using `memcpy()` to assign a pointer an address
是
memcpy( ptr, &value, sizeof(char *) );
与...相同
ptr = &value;
.....
我以前从未见过memcpy()
用于执行此操作。 似乎我应该用“嗯,你没错”这句话来回应此代码的开发人员。 似乎有些多余。
编辑:似乎重要的是要注意ptr
是void * ptr
。 value
是double value
。
Edit2:对于那些有兴趣跟着这个问题进行研究的人,请与我一起阅读。 静态分析将这部分代码标记为潜在的缓冲区溢出。 静态分析担心目标缓冲区ptr
可能没有足够的空间来保存sizeof(char *)
为sizeof(char *)
的信息。
我没有去解决它给我带来的问题,而是试图确切地了解此memcpy()
所做的事情(感谢您的帮助)。 一旦了解了所发生的事情,就必须理解为什么赋予memcpy()
的内存大小为sizeof(char *)
; 此memcpy()
所在的函数被调用一次,并且该调用看起来像这样:
SdmJniGetPointer(blah, blah, &ptr)
这意味着该函数内以及memcpy()
调用中ptr
的实际值是另一个指针的地址!
对我来说,以前的开发人员会memcpy()
一个sizeof(char *)
的数据量真是让我感到很奇怪,因为该系统是在32位和64位计算机上编译的。 但是,由于他将指向指针( &ptr
)的地址作为ptr
传递到函数中,因此他不仅避免了根据系统体系结构从4字节指针转换为8字节指针的过程,而且还完全按照他的意思进行了操作(我认为)。 最后,在64位系统上,所有double value
都将被复制到ptr
指向的地址中,该地址实际上是指向另一个指针( &ptr
)的地址,而在32位计算机上,一半的值将被复制。的位置ptr
这实在是&ptr
。 现在,我只需要弄清楚那个double value
真正代表什么,以及他为什么可以将其对等。
如果那没有道理,我会再试一次,但是感觉就像他在盗版一样。 =)
不,完全不同。 让我们添加一些类型:
char *addr;
char **ptr = &addr;
char *value = "Hello";
memcpy(ptr, &value, sizeof(char *));
// Equivalent to...
*ptr = value;
如果可以使用=
代替,最好避免使用memcpy()
。
除其他事项外,如果类型不正确,则=
将生成正确的诊断信息,而memcpy()
将使您的程序崩溃甚至更糟。
根据类型,
double value, value2;
void *ptr = &value2;
// This copies `value` into `value2`.
memcpy(ptr, &value, sizeof(double));
使用sizeof(char *)
是错误的,因为如果要复制double
,则应该为sizeof(double)
。
从理论上讲,您可能会做一些更深奥的事情,但我会忽略这种可能性。
这将更改指针ptr
指向的地址 :
ptr = &value;
这将更改指针ptr
指向的地址处的数据 :
memcpy(ptr, &value, sizeof(char*));
在第二种情况下, ptr
仍指向与调用前相同的地址。 所以他们绝对不是一样的。
那memcpy
就像
*ptr = value;
因此, ptr
必须指向一个char *
(假设value
是根据sizeof
)。
假设ptr
是char **
(或者您将其更改为采用ptr
的地址: &ptr
)并正确初始化,那么我在这里没有发现实际问题。 但是,此代码禁止编译器进行类型检查,并且可能比简单的分配慢。
如果源和目标具有不同的类型(如编辑所暗示的),它也可能会出现别名问题。 它还可能会禁止优化。
哦,而且:该代码更难以阅读/手动验证/理解,IOW:难以维护(如注释和我自己的编辑所示)。 也许开发者因混淆而追求工作安全?
编辑:
编辑后添加类型信息:该代码甚至更糟。 它甚至不使用相同的类型。 我的建议:将作者踢到真正受伤的地方,然后非常仔细地重写代码。 注意:无论谁写这样的代码,很可能在其他地方写更多的废话。
与使用memcpy相比,赋值表示法更为简洁和易读,并允许编译器优化。 =
表示分配,而memcpy仅复制内存。
您应该坚持=
赋值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.