Действительно ли хорошо отправить стеку выделенный объект как параметр указателя к некоторой другой функции?

Просто некоторые дженерики не были выведены. Попробуйте указать их явно

  type AllErrorsOr[A] = Validated[List[String], A]

  def bothInvalid: AllErrorsOr[(Int, Int)] = {
    Semigroupal[AllErrorsOr].product[Int, Int](
      Validated.invalid(List("Error 1")),
      Validated.invalid(List("Error 2"))
    )
  }

  def bothInvalidTuple: AllErrorsOr[(Int, Int)] = {
    Semigroupal.tuple2[AllErrorsOr, Int, Int](
      Validated.invalid(List("Error 1")),
      Validated.invalid(List("Error 2"))
    )
  }

  def bothValid: AllErrorsOr[(Int, Int)] = {
    Semigroupal[AllErrorsOr].product[Int, Int](
      Validated.valid(10),
      Validated.valid(20)
    )
  }

  def bothValidTuple: AllErrorsOr[(Int, Int)] = {
    Semigroupal.tuple2[AllErrorsOr, Int, Int](
      Validated.valid(10),
      Validated.valid(20)
    )
  }
7
задан yesraaj 13 April 2009 в 08:03
поделиться

6 ответов

Да, но более распространенной идиомой C ++ для этой ситуации является использование ссылки (и, вероятно, ссылки на const) вместо указателя. Таким образом, вместо

void foo( sometype * p ) {
   p->func();
}

вы пишете:

void foo( sometype & p ) {
   p.func();
}

Это имеет то преимущество, что вам не нужно разыменовывать объект в вызывающей стороне:

void afunc() {
   sometype t;
   foo( t );
}

, а также дает подсознательный намек читателю, что вы не намереваетесь использовать функцию принять право собственности на объект.

12
ответ дан 6 December 2019 в 05:43
поделиться

Если вы уверены, что вызов является синхронным, то вполне допустимо отправить адрес выделенного объекта стека в функцию , В случае, если вызов асинхронный (т. Е. Вызванная вами функция передает указатель в другой поток), он определенно создаст проблемы, так как вы можете попытаться получить доступ к адресу памяти из другого потока, даже после уничтожения выделенного стека объекта.

10
ответ дан 6 December 2019 в 05:43
поделиться

Пока функция приема не предполагает, что она получает право собственности на ресурс (и пытается освободить его) , конечно. Ссылка может быть лучшей идеей, хотя.

6
ответ дан 6 December 2019 в 05:43
поделиться

Это прекрасно для синхронного вызова функции. Если вызов асинхронный, это может привести к сбою при удалении стекового объекта, когда он выходит из области видимости.

2
ответ дан 6 December 2019 в 05:43
поделиться

Вы должны быть осторожны, чтобы не хранить этот указатель для дальнейшего использования. Например:

void store(int* param) {
     // Store pointer in some global storage for further use
     global_storage.add_param(param); 
}
void func() {
    int test_var = 5;
    store(&test_var); // Pass the pointer to the global storage
} 
// At this point stack object test_var will be destroyed
// Global storage contains a pointer, that points to some garbage
2
ответ дан 6 December 2019 в 05:43
поделиться

Это, конечно, верно, но со многими оговорками. Вот главные моменты, о которых следует помнить (некоторые уже упоминались другими, некоторые нет).

  • Указатель сам по себе может означать, что владение ресурсом передается вызываемому (то есть они должны освободить его после использования). Здесь есть ссылка.
  • Во многих ситуациях функция, которую вам нужно вызвать, уже определена, и вы не можете ее изменить, вы должны изучить ее поведение и убедиться, что она не предполагает, что она будет владеть объектом, сохраните его статически или скопируйте в другое место.
  • Если вызываемая функция должна взять нулевой указатель, указывающий на отсутствие указанного параметра, у вас не будет выбора использовать ссылку.
  • Асинхронные вызовы абсолютно нет-нет (если, конечно, вы не заблокируете, пока они не будут выполнены, используя ваш локальный объект, а затем вернетесь).
  • Вызываемая функция никогда не должна ни при каких обстоятельствах обращаться за пределы размера рассматриваемого объекта, это разрушит ваш стек и почти наверняка приведет к краху вашей программы!
  • Вызов функции, чувствительной к доступу к байту, превышающему размер Объект может быть обязанностью безопасности. На самом деле, это самый распространенный способ взлома защищенных систем. Это называется переполнением буфера. (выходит за рамки вашего вопроса, но вы можете прочитать больше здесь и здесь )
1
ответ дан 6 December 2019 в 05:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: