使用`memcpy()`为地址指定一个指针

时间:2015-06-24 21:13:36

标签: c++ c pointers memory memcpy

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

相同
ptr = &value;

.....

我以前从未见过memcpy()曾经这样做过。 似乎我应该用这句话回答这段代码的开发者“嗯,你没有错。”它看起来有点像它需要的一样。

修改:注意ptrvoid * ptr似乎很重要。 valuedouble value

Edit2:对于那些有兴趣跟随这个问题的人,请跟着我的兔子洞一起读。这段代码被静态分析标记为潜在的缓冲区溢出。静态分析担心目标缓冲区ptr可能没有足够的空间来容纳sizeof(char *)的信息。
它没有处理它给我的问题,而是试图准确理解这个memcpy()做了什么(谢谢你帮助我)。一旦我理解了发生了什么,我就必须理解为什么memcpy()给出的内存大小为sizeof(char *);这个memcpy()所在的函数被称为一次,而这一次看起来像这样:

SdmJniGetPointer(blah, blah, &ptr)

意味着此函数和ptr调用中memcpy()的实际值是另一个指针的地址!

我觉得以前的开发人员会memcpy() sizeof(char *)数据量,因为这个系统是在32位和64位计算机上编译的。但是,因为他将地址作为指针(&ptr)传递给函数ptr,他不仅绕过了从4字节指针到8字节指针的转换,这取决于系统架构,完全按照他的意思使用它(我认为)。最后,在64位系统上,所有double value都被复制到ptr指向的地址,这实际上是不同指针(&ptr)的地址,并且在32位计算机上,其中一半被复制到真正ptr的{​​{1}}位置。现在我只需要弄清楚&ptr真正代表什么,以及为什么他可以将它平分。

如果这没有意义,我会再试一次,但感觉就像是他的指针一样。 =)

4 个答案:

答案 0 :(得分:2)

不,这完全不同。让我们添加一些类型:

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 *)是错误的,因为如果您要复制sizeof(double),它应为double

从理论上讲,你可能会做一些更深奥的事情,但我会忽略这种可能性。

答案 1 :(得分:2)

这会更改指针ptr指向的地址

ptr = &value;

这会更改指针ptr指向的地址处的数据

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

在第二种情况下,ptr仍指向与呼叫前相同的地址。所以它们绝不是一样的。

答案 2 :(得分:1)

memcpy就像

*ptr = value;

所以ptr必须指向char *(根据value假设sizeof

假设ptrchar **(或者您更改为ptr&ptr的地址)并正确初始化,我认为没有实际问题此处即可。但是,此代码禁止编译器进行类型检查,并且可能比简单赋值慢。

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

哦,并且:该代码更难以阅读/手动验证/理解,IOW:维护(如评论和我自己的编辑所示)。也许开发人员通过混淆来处理工作安全问题?

修改

编辑后添加类型信息:该代码更糟糕。它甚至不使用相同的类型。我的建议:将作者踢到真正伤害的位置,然后仔细重写代码 very 。注意:编写此类代码的人很可能会在其他地方写下更多垃圾。

答案 3 :(得分:0)

使用memcpy,分配符号更简洁,更易读,并允许编译器优化。 =表示分配,而memcpy只是复制内存 您应该坚持使用=作业