简体   繁体   English

调用函数后的值通过引用传递给 C++ 中的指针?

[英]Value after call function which passing by reference to pointer in C++?

i cannot understand why the value of *p and *p1 change after cout their value in the code lines below.我无法理解为什么 *p 和 *p1 的值在下面的代码行中计算出它们的值后会发生变化。 thank you for your help.感谢您的帮助。

void g(int *&x) {
    int a = 3;
    x = &a;
}
void h(const int *&x) {
    int b = 2;
    x = &b;
}

int main() {
    int *p = new int;
    *p = 5;

    g(p);
    cout << p << " " << *p << endl; // 0095FD48 3 *why the value change in the next line? *
    cout << p << " " << *p << endl; // 0095FD48 1829755776 
    const int*p1 = p;
    h(p1);
    cout << p << " " << *p << endl; // 0095FD48 2 *in here it happen, too*
    cout << p << " " << *p << endl; // 0095FD48 1829755776 
}

g() and h() assign the address of a local variable to the parameter and thereby expose the address to the caller. g()h()将局部变量的地址分配给参数,从而将地址暴露给调用者。 When these functions return, the local variable is freed, ie, its place on the stack may be re-used.当这些函数返回时,局部变量被释放,即它在堆栈中的位置可以被重新使用。

Therefore, this is undefined behavior.因此,这是未定义的行为。 In your example, it is a case of "use after free".在您的示例中,这是“免费使用”的情况。

The calls to cout and its operator<< use some portion of the stack and overwrite the "former local variable".cout及其operator<<的调用使用堆栈的某些部分并覆盖“以前的局部变量”。

There are several fixes for your sample code, depending on what you want to achieve:您的示例代码有几个修复程序,具体取决于您要实现的目标:

  1. If you want your function to modify the value of *p of the main function, then do not introduce a new integer variable in g() , but access the existing one: void g(int *&x) { *x=3; }如果你想让你的函数修改主函数*p的值,那么不要在g()引入一个新的整数变量,而是访问现有的: void g(int *&x) { *x=3; } void g(int *&x) { *x=3; }

  2. Is basically the same as (1), but you without references instead of pointers.与(1)基本相同,但是你不用引用而不是指针。 void g(int &x) { x=3; // x is no local variable but references the callers argument }

  3. Allocate a new variable.分配一个新变量。 void g(int *&x) { x = new int; // allocate int value on heap *x = 3; } void g(int *&x) { x = new int; // allocate int value on heap *x = 3; } Because you pass a pointer as reference, the former pointer value will be overwritten, which may lead to a memory leak. void g(int *&x) { x = new int; // allocate int value on heap *x = 3; }因为你传递一个指针作为参考,前指针值将被覆盖,这可能导致内存泄漏。
  4. Same as (3) but using a return value and thereby reducing the risk of memory leaks: int * g() { int *x = new int; // allocate int value on heap *x = 3; return x; }与 (3) 相同,但使用返回值,从而降低内存泄漏的风险: int * g() { int *x = new int; // allocate int value on heap *x = 3; return x; } int * g() { int *x = new int; // allocate int value on heap *x = 3; return x; }

  5. To avoid memory leaks, you may use "automatic pointers", see http://www.cplusplus.com/reference/memory/unique_ptr/为避免内存泄漏,您可以使用“自动指针”,请参阅http://www.cplusplus.com/reference/memory/unique_ptr/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM