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



Is

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

ptr = &value;

.....

我以前从未见过memcpy()曾经这样做过。似乎我应该用短语"好吧,你没有错"来回应这段代码的开发人员。这似乎比它需要的要罗嗦一些。

编辑:似乎重要的是要注意ptr void * ptrvaluedouble value.


编辑2:对于那些有兴趣和我一起关注这个问题的人,请继续阅读。 静态分析将这段代码标记为潜在的缓冲区溢出。 静态分析担心目标缓冲区ptr可能没有足够的空间来保存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真正代表什么,以及为什么他可以将其一分为二。

如果这没有意义,我会再试一次,但感觉就像他在启动指针。 =(

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

ptr = &value;

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

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

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

不,这是绝对不同的。 让我们添加一些类型:

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)

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

memcpy就像

*ptr = value;

所以ptr必须指向一个char *(根据sizeof,假设value是(。

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

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

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

编辑:

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

赋值表示法比使用 memcpy 更加简洁易读,并允许编译器优化。 =意味着分配,而memcpy只是复制内存。
你应该坚持=作业

最新更新