取消引用指针以设置值与为指针分配地址?

dereferencing a pointer to set a value vs. assigning an address to the pointer?

有人可以解释以下两段代码之间的区别吗? 在下面的函数中,*frame_id可能是一个nullptr,它基本上是函数中的输出参数。

bool LRUReplacer::Victim(frame_id_t *frame_id) {
  long oldest_ts = std::numeric_limits<long>::max();
  for (auto & it : this->LRUCache){
    if (it.ts < oldest_ts){
      oldest_timestamp = it.ts;
      *frame_id = it.frame_id;
    }
  }

对比

bool LRUReplacer::Victim(frame_id_t *frame_id) {
  long oldest_ts = std::numeric_limits<long>::max();
  for (auto & it : this->LRUCache){
    if (it.ts < oldest_ts){
      oldest_timestamp = it.ts;
      frame_id = &it.frame_id;
    }
  }

在第一种情况下,我们将 frame_id 赋给 it.frame_id 的值,而在第二种情况下,我们将指针赋给 it.frame_id?

的地址

第一个是用新值替换 frame_id 指向的值。第二个是 尝试 替换给定的指针,使其指向别的东西。但是不行。

你在堆栈上得到了一个指针并重置它。这不会传回给调用者。他将被他传递给你的价值所困。除非你通过引用传递它

如果你想让第二个工作,你需要将签名更改为:

bool LRUReplacer::Victim(frame_id_t*& frame_id) {

让我们考虑一个与reading/writing/dereferencing基本相同的简化示例:

void f1(int* value)
{
    *value = 1;
}

int g_value = 1;

void f2(int* value)
{
    value = &g_value;
}

int main()
{
    {
        int value = 2;
        f1(&value);
        std::cout << value << '\n'; // prints 1
    }


    {
        int value = 2;
        f2(&value);
        std::cout << value << '\n'; // prints 2
    }
}

请注意,您只是在第二个备选方案中重新分配了参数。参数是按值传递的指针值,因此对于调用者传递的指针指向的变量绝对没有影响。

在 C++ 中,最好使用引用:

void f3(int& value)
{
    value = 1;
}

int main()
{
    int value = 2;
    f3(value);
    std::cout << value << '\n'; // prints 1
}

在第一个循环中,如果it.ts < oldest_ts你将把it.frame_id的值赋给frame_id指向的frame_id_t。循环完成后,frame_id_t 实例 (*frame_id) 将保留分配给它的最后一个值。

在第二个循环中,您会将 it.frame_id 的地址分配给 frame_id_t* (frame_id)。循环完成后,frame_id 将指向最后一个 it.frame_id 它被设置为指向。