指针函数参数在C++中的复制和性能

Pointers function arguments copy and performance in C++

本文关键字:复制 性能 C++ 函数 参数 指针      更新时间:2023-10-16

第一个问题:

很多时候,我们通过使用指针的函数调用将一个对象的引用传递给另一个对象。例如:

int num =25;
int *num1Ptr=#
int *num2Ptr=NULL;
void assinNum (int *numPtr){
    num2Ptr = numPtr; ////we copy the value (address) of the num1Ptr pointer to num2Ptr
}

我的问题是:如果这样的方法被频繁调用,我们是否会期望指针复制的大量开销?

第二个问题:

在下面的场景中,这是否意味着我们将传递的numPtr所指向的内存地址中的值复制到num2Ptr所指向的存储器地址?如果是,那么它与传递值相同?

int num =25;
int *num1Ptr=#
int *num2Ptr=NULL;
void assinNum (int *numPtr){
    *num2Ptr = *numPtr; ////num2Ptr points to the same value in the memory pointed by numPtr argument. 
}

第一个问题的更新:

指向大型对象(而不是基元(的指针的结果是什么?

如果这样的方法被频繁调用,那么指针复制的开销会很大吗?

指针通常只是一个32位或64位的量。因此,复制指针只需要复制32位或64位的数量,这在大多数平台上非常便宜。然而,直接复制int也非常便宜,因此在这种情况下,使用指针可能不会给您带来太多好处。

同样值得指出的是,在许多情况下,编译器会通过内联来优化这个函数

这是否意味着我们将传递的numPtr所指向的内存地址中的值复制到num2Ptr所指向的存储器地址?

理论上是的。但是,num2Ptr = NULL,所以您的代码很可能会导致分段错误。

那么它和传递值是一样的?

我不知道你指的是什么,所以很难知道如何回答这个问题!

如果这样的方法被频繁调用,那么指针复制的开销会很大吗?

"开销"意味着你正在将一些可选或虚假的工作与实际需要完成的工作量进行比较,以达到特定的预期效果。总工作量和最低要求工作量之间的差异是间接费用。在这种情况下,还不清楚你的基线是什么。你会考虑什么开销?将一个指针复制到另一个指针的操作非常小——这只是一个32或64位的赋值,具体取决于您的目标平台。这样的手术不是免费的,但速度很快。

由passed numPtr指向的内存地址到由num2Ptr指向的内存位置?

是的,您显示的代码将numPtr引用的内存中的值复制到numPtr2引用的内存。当然,在您的示例中,指针分别引用地址0x00000019和0x00000000,所以在读取源值时会崩溃,除非您知道那里有可读内存;写东西时崩溃,除非你知道你也有可写内存(而且你可能没有(。请注意,您的评论(////num2Ptr points to the same value in the memory pointed by numPtr argument.(不正确。

如果是,那么它与传递值相同?

传递指针与传递值不同。指针是对数据的引用,而不是数据的值。(当然,指针本身是通过值传递的,但你应该取消对它的引用。(由于指针是可写的,你可以向它写入,调用方在返回时会看到这种写入的效果。

我的问题是:如果这样的方法被频繁调用,我们是否会期望指针复制的大量开销?

用于复制sizeof(int*)?不可以。但是,对于函数调用,可能会有很大的开销,尤其是如果调用是通过PLT执行的。在多线程环境中,这可能会间接引入其他开销。

在下面的场景中,这是否意味着我们将传递的numPtr所指向的内存地址中的值复制到num2Ptr所指向的存储器地址?

是的。

如果是,那么它与传递值相同?

没有。按值传递整数更快,主要是因为按值传递不涉及读取内存,而是通过寄存器完成。

指针复制的成本非常低,但对于指针大小与存储数据一样大或更大的原始数据类型来说,这没有什么意义。

对于你的第二个问题,你正在应对价值,这与通过价值来应对是一样的。