繁体   English   中英

使用`memcpy()`为指针分配地址

[英]Using `memcpy()` to assign a pointer an address

memcpy( ptr, &value, sizeof(char *) );

与...相同

ptr = &value;

.....

我以前从未见过memcpy()用于执行此操作。 似乎我应该用“嗯,你没错”这句话来回应此代码的开发人员。 似乎有些多余。

编辑:似乎重要的是要注意ptrvoid * ptr valuedouble 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 )。

假设ptrchar ** (或者您将其更改为采用ptr的地址: &ptr )并正确初始化,那么我在这里没有发现实际问题。 但是,此代码禁止编译器进行类型检查,并且可能比简单的分配慢。

如果源和目标具有不同的类型(如编辑所暗示的),它也可能会出现别名问题。 它还可能会禁止优化。

哦,而且:该代码更难以阅读/手动验证/理解,IOW:难以维护(如注释和我自己的编辑所示)。 也许开发者因混淆而追求工作安全?

编辑:

编辑后添加类型信息:该代码甚至更糟。 它甚至不使用相同的类型。 我的建议:将作者踢到真正受伤的地方,然后非常仔细地重写代码。 注意:无论谁写这样的代码,很可能在其他地方写更多的废话。

与使用memcpy相比,赋值表示法更为简洁和易读,并允许编译器优化。 =表示分配,而memcpy仅复制内存。
您应该坚持=赋值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM