Tengo una secuencia de llamadas donde la llamada final requiere un puntero doble. Parece que siempre obtengo un puntero nulo al final. He simplificado mucho esto a lo siguiente. La llamada final es una llamada a la biblioteca que devuelve un puntero.

Este es el desastre simplificado. El foo en MainCaller siempre es 0 aunque sé (a través de los métodos de prueba de bibliotecas) que el objeto existe.

void MainCaller(){
    foo_t *foo;
    MiddleProcessor(foo);
    // foo results as 0
}

void MiddleProcessor(foo_t *foo){
  if(1){
    ProcessorA(foo);
  }else{
    ProcessorB(foo);
  }
}

void ProcessorA(foo_t *foo){
    FinalCall(&foo);
}

void FinalCall(foo_t **foo){
    *foo = some_lib_call();
    lib_call_test_is_good_foo(foo); // true :)
}
c++
0
J Doe. 2 mar. 2018 a las 23:58

3 respuestas

La mejor respuesta

Los problemas son que pasa el puntero por valor y FinalCall nunca sabe dónde vive el original.

Estos cambios pueden ayudar:

void MainCaller(){
    foo_t *foo;
    MiddleProcessor(&foo); // Passing the address of foo means foo can be overwritten
    // foo results as 0
}

void MiddleProcessor(foo_t **foo){
  if(1){
    ProcessorA(foo);
  }else{
    ProcessorB(foo);
  }
}

void ProcessorA(foo_t **foo){
    FinalCall(foo);
}

void FinalCall(foo_t **foo){
    *foo = some_lib_call();
    lib_call_test_is_good_foo(foo); // true :)
}
3
quamrana 2 mar. 2018 a las 21:05

Cambiar foo en FinalCall no tiene efecto en foo en MainCaller. Son diferentes variables, ¿por qué cambiar una cambia la otra?

En cambio, quieres algo como esto

void MainCaller(){
    foo_t *foo;
    foo = MiddleProcessor();
}

foo_t* MiddleProcessor(){
  if(1){
    return ProcessorA();
  }else{
    return ProcessorB();
  }
}

foo_t* ProcessorA(){
    foo_t* foo;
    FinalCall(&foo);
    return foo;
}

void FinalCall(foo_t **foo){
    *foo = some_lib_call();
    lib_call_test_is_good_foo(foo); // true :)
}
2
john 2 mar. 2018 a las 21:02

Para modificar un parámetro, debe pasar por referencia, lo que puede hacer con una referencia explícita o un puntero. Si lo que desea cambiar es un puntero, necesita una referencia a un puntero o un puntero a un puntero.

0
Mark Ransom 2 mar. 2018 a las 21:10