es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Tipo incompleto en estructuras.

¡Hola!

Tengo un problema y una pregunta. Espero que puedas ayudarme y explicarme.

En primer lugar, tengo 2 estructuras:

typedef struct {
    double x;
    double y;
} A;
typedef struct  {
    unsigned int count;
    A(*stack)[]; 
} B;

Declaro esta estructura B en la función main() y paso un puntero de B a una función que lo inicializa.

main(){
    B x;
    function rr(&x);
}
void rr(B* test){
    test->stack = malloc((4) * sizeof(A)); // 4 elementos
    for (unsigned int i = 0; i < 4; i++) {
        (test->stack + i)->x = 89;
    }
}

En esta línea (test->stack + i)->x = 89;, el compilador dice “tipo incompleto”. Sé por qué está incompleto, porque en la estructura B no hay una dimensión. Pero el arreglo debería inicializarse en la función rr.

Tal vez entiendas lo que quiero decir y cómo solucionar mi problema. No se me permite cambiar la función rr.

Saludos.

EDIT 1

Gracias por todas las respuestas. Tal vez debería aclarar mi problema.

typedef struct  {
    unsigned int count;
    A(*stack)[]; // aquí quiero un puntero a un arreglo de A
} B;

// Se declara en la función main
void rr(B*);

main(){
    B x;
    function rr(&x);
}

// No se permite cambiar esta función
void rr(B* test){
    test->stack = malloc((4) * sizeof(A)); // 4 elementos
    for (unsigned int i = 0; i < 4; i++) {
        (test->stack + i)->x = 89; // error debido al tipo incompleto pero necesito usar esta línea
    }
}

Espero que ahora sea más fácil entender lo que quiero.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código es que en la definición de la estructura B, el arreglo stack se declara como un puntero a un tipo incompleto. Esto significa que si bien el compilador sabe que stack es un puntero, no conoce el tamaño o el contenido del arreglo al que apunta.

    Para resolver este problema, el arreglo stack en la estructura B debería declararse con un tamaño, o como un puntero a un arreglo de tipo A asignado dinámicamente. Si el tamaño del arreglo en B es constante y se conoce en tiempo de compilación, se puede declarar de la siguiente manera:

    typedef struct  {
        unsigned int count;
        A stack[4];
    }B;
    

    Esto declara un arreglo stack de 4 elementos de tipo A dentro de la estructura B. Ahora cada elemento del arreglo se puede acceder directamente, sin necesidad de aritmética de punteros.

    Sin embargo, si el tamaño del arreglo stack no se conoce en tiempo de compilación o es variable, el arreglo debe declararse como un puntero a un arreglo asignado dinámicamente usando malloc(), como en el código original. Sin embargo, la sintaxis correcta para asignar valores a los miembros del arreglo es:

    (*(test->stack + i)).x = 89;
    

    Los corchetes alrededor de la expresión test->stack + i son necesarios debido a las reglas de precedencia de operadores en C. Sin los corchetes, el compilador intentaría acceder primero al miembro x de test, lo cual no es lo que queremos.

    Por lo tanto, el código modificado para la estructura B y la función rr() se vería así para un arreglo asignado dinámicamente:

    typedef struct  {
        unsigned int count;
        A (*stack)[];
    }B;
    
    void rr(B* test) {
       test->stack = malloc(4 * sizeof(A));
       for (unsigned int i = 0; i < 4; i++) {
            (*(test->stack + i)).x = 89;      
        }
    }
    

    Es importante destacar que es necesario liberar la memoria asignada por malloc() cuando ya no se necesite para evitar fugas de memoria.

Comments are closed.