将堆栈分配的对象作为指针参数发送到其他一些函数是否合适?

时间:2009-04-13 08:03:30

标签: c++ function parameters

将堆栈分配的对象作为指针参数发送给其他函数是否合适?

6 个答案:

答案 0 :(得分:12)

是的,但对于这种情况,更常见的C ++习惯用法是使用引用(可能是const引用)而不是指针。而不是

void foo( sometype * p ) {
   p->func();
}
你写道:

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

这样做的好处是您不需要取消引用调用者中的对象:

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

并且还向读者提供潜意识提示,即您不打算将该函数用于获取对象的所有权。

答案 1 :(得分:10)

如果您确定该调用是同步的,那么将堆栈分配对象的地址发送给该函数是完全有效的。如果调用是异步的(即您调用的函数将指针传递给另一个线程),那么它肯定会产生问题,因为即使在堆栈分配的对象被破坏后,您也可能尝试从不同的线程访问内存地址。

答案 2 :(得分:6)

只要接收功能没有假设它获得资源的所有权(并试图释放它),当然。但参考可能是一个更好的主意。

答案 3 :(得分:2)

它非常适合同步函数调用。如果调用是异步的,当堆栈对象超出范围时,它可能会导致崩溃。

答案 4 :(得分:2)

您应该注意不要存储该指针以供进一步使用。例如:

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

答案 5 :(得分:1)

这当然有效,但有许多警告。以下是要记住的最重要的事情(有些已经被其他人提及,有些则没有。)

  • 指针本身可能意味着资源所有权被传递给被调用者(即他们必须在使用后释放它)。这里有一个参考。
  • 在许多情况下,您需要调用的函数已经定义,您无法更改它,您必须研究它的行为,并确保它不会假定它将拥有该对象,静态存储或将其复制到其他位置。
  • 如果您正在调用的函数需要使用空指针来指示缺少所述参数,则您将无法选择使用引用。
  • 异步调用绝对是禁止的(除非你在使用本地对象完成然后返回之前阻塞它们。)
  • 被调用的函数永远不会在任何情况下访问超出相关对象的大小,这将破坏您的堆栈,几乎肯定会使您的程序崩溃!
  • 调用易于访问超出对象大小的字节的函数可能是安全责任。实际上,这是打入安全系统的最常用方法。这称为缓冲区溢出。 (超出了您的问题范围,但您可以阅读更多herehere