将结构或memcpy的void指针强制转换为新结构?

时间:2014-03-18 11:05:32

标签: c++ pointers casting

我将void *作为参数传递给调用函数foo(void* parm)的函数bar(STmyStruct* parm) 我应该将void指针强制转换为STmyStruct*还是创建一个新结构,memcpy void*指向什么,然后传递指向该结构的指针? 我猜解决方案A效率更高?

A:    foo(void* parm)
      {
       bar((STmyStruct*) parm)
      }

B:    foo(void* parm)
      {
       STmyStruct myStr;
       memcpy(&myStr, parm, sizeof(STmyStruct));
       bar(&myStr)
      }


bar(STmyStruct* mystr);

4 个答案:

答案 0 :(得分:2)

  • 如果您可以完全避免交易void*,请执行此操作。但您可能受现有API的约束。
  • 如果void*实际指向STmyStruct*,则只需投出。
  • 如果void*没有指向STmyStruct*但是某些布局兼容(因此交叉memcpy是合法的),这应该是一个非常罕见的情况,那么你必须由于别名规则,请使用选项B,否则可能会使编译器感到困惑。

答案 1 :(得分:1)

实际上这两个解决方案做了不同的事情,解决方案A你通过引用传递参数,所以如果你在函数bar里面改变了什么,你会改变传递给foo的东西,这意味着:

STmyStruct test;
// your code that uses test
foo(test);

如果功能栏改变了mystr参数,你也会改变测试。

但是在解决方案B中,您使用memcpy复制参数parm,因此如果函数bar更改其参数,您将无法更改parm。这意味着:

STmyStruct test;
// your code that uses test
foo(test);

即使您在功能mystr内更改参数bar,测试也不会发生变化,因为您将其值复制为myStr

答案 2 :(得分:0)

这取决于您的使用案例。通常,两者都很好,假设parm确实指向STMyStruct类型的对象。

如果bar修改mystr并且您希望修改原始param,则必须使用选项A.

如果修改mystr并且您不希望修改param,则需要选项B.

如果bar不修改mystr,那么A会更有效率,但B也不会有问题。 (除非B在任何地方存储指向mystr的指针。)

答案 3 :(得分:0)

这取决于您是否希望bar修改您指定的项目,或者您是否希望它在副本上工作。