Hay una manera de restablecer las variables declaradas como static dentro de una función? El objetivo es asegurarse de que la función no está llamado con la permanencia de los valores a partir de una relación de llamada. Por ejemplo, tengo una función opearting en las columnas de una matriz.

int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows 
   if (column != whichColumn){
    memset(v,0,size);
    whichColumn = which;
   } 
   //do other things
}

Se llama a la función n veces, una para cada columna. Es esta la manera correcta de «re-configuración» de la variable estática? Hay otros generales infalible maneras de restablecer las variables estáticas? Por ejemplo, quiero asegurarme de que si la llamada se realiza con una nueva matriz, con posibilidad de diferentes dimensiones, entonces el vector v es de tamaño y no dudo etc. Parece que la forma más fácil puede ser para llamar a la función con un puntero NULL:

int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows 
   if (A == NULL){
    FREE(v);
    whichColumn = 0;
   } 
   //do other things
}
No use static/variables globales. En lugar de pasar a la función de un puntero a un entero que la persona que llama se mantiene para preservar el estado a través de llamadas.
Sólo he tenido un problema similar wehre tuve que resetear mi las variables estáticas, pero sólo en mi código de prueba. Mi hack fue para establecer la entrada de punteros a NULL, comprobar que en la func, a continuación, reiniciar la variable según corresponda – de manera efectiva el uso de un valor NULO en un parámetro existente como una bandera. un poco mal olor, pero funciona.
una clase con variables de miembro estático sería la solución ideal tal vez, pero con C (sin programación orientada a objetos) tal vez un static struct es, probablemente, el más cercano solución elegante.
lo siento volver a leer el post inicial con más cuidado – me he efectivamente vienen con la misma solución, rápida y sucia – no puedo pensar en nada mejor que iba a ser tan rápido para implementar

OriginalEl autor Sue | 2010-08-15

5 Comentarios

  1. 0

    Me gustaría recomendar convertirlo en una estructura y escribir una pequeña función auxiliar para la administración de la semántica de lo que estamos tratando de hacer. Podría volver el buffer si la solicitud es apropiada para su tamaño, o crear una nueva en la demanda (y el viejo), si es necesario.

    Escribir una clase contenedora? En C?
    Huy, cómo sobre una estructura + de auxiliar de la función?
    Gracias Jesse, he utilizado un híbrido de la teo enfoques como mi comentario para Borealid indica. «Reset» sigue siendo administrado por la función para ocultar los detalles en el exterior. No sé C++, por lo que la clase de contenedor es ootq.

    OriginalEl autor Jesse Collins

  2. 3

    Utilizar un idempotente inicializador de la función y las variables globales en su lugar.

    Por ejemplo:

    int foo;
    int *m = NULL;
    
    static void InitVars() {
        foo = 0;
        if (m != NULL) {
            free(m);
        }
        m = malloc(sizeof(int)*5);
        memset(m, 0, sizeof(int)*5);
    }

    Si su inicializador es realmente idempotente, se le puede llamar de nuevo para restablecer las variables.

    Si necesidad este ser llamado «automágicamente», el uso de __attribute__((constructor)) (GCC) así:

    static void InitVars __attribute__((constructor)) ();

    Sin embargo, debe tener en cuenta que si usted necesita para hacer esto, usted debe reconsiderar el uso de la función de static variables y utilizar en su lugar el pasado-en las frescas, que son devueltos/escrito y se pasa a posteriores relacionadas con las llamadas.

    Hola Gracias por la respuesta. Decidí seguir el consejo y no uso *v como una variable estática – en lugar de sólo usar whichColumn como un statitc variable. v ahora es parte de la estructura recomendada por Jesse a continuación. la aprobación de la columna = -1) restablece la statitic variable y reinitalizes el trabajo vectorial. A continuación, se actualiza de forma apropiada para cada momento (columna != whichColumn). Su otra sugerencia parece útil y voy a aprender acerca de él. Gracias de nuevo. sm
    hmm – esto parece un poco arriesgado – no es seguro que la solución más robusta con esas variables globales colgando alrededor de

    OriginalEl autor Borealid

  3. 0

    Un método que he observado que se utilizan cuando un módulo de C fue importado a C++ fue a rodear el módulo entero con un contenedor de clase, y reemplazar todas las variables estáticas dentro de las funciones con el único denominado «global» varaibles fuera de las funciones. Yo no conozco a ningún buen camino para lograr un efecto similar para los proyectos que involucran a múltiples archivos de código fuente, aunque me gustaría saber si existe uno. Tengo algunas de sistemas embebidos en C, que me simular mediante la adición de algunos envoltorios de C++ en VS2005. Por ejemplo, tengo registros de e/S definidos, por lo que algo como TX1CON = 0x5C; podría traducir en algo así como IOMAP(0x251).P = 0x5C; IOMAP es una propiedad que se iba a enviar a «escribir 0x5C a la dirección de 0x251» hardware-programa de simulación. Este enfoque funciona bien, pero no puedo hacer un reinicio completo. Alguna idea?

    el problema con esto es que usted termina con un montón más funciones == código de la hinchazón. además de que están simplemente empujando la responsabilidad de la escalera de mano que en última instancia conduce a que el ‘dios’ de la función anti-patrón. No creo que es obvio que «limpia» la solución a este para un no lenguaje OOP
    En el caso concreto que he descrito con los envoltorios de C++ en VS2005, el código sobrecargar sólo se produjo en un contexto de simulación. Puesto que el verdadero sistema de 128 kb de ROM y 4K de RAM, y el entorno de simulación había gigas de RAM, y desde el sistema real probablemente corrió en bruto «código» menos del 1% tan rápido como el entorno de simulación, mi preocupación era la escritura de código en tal manera como para ser eficiente en el sistema real, sin tener en cuenta si la eficiencia en la simulación de contexto. Otras situaciones podría tener otros requisitos.

    OriginalEl autor supercat

  4. 0

    Un enfoque que a veces puede ser útil si se necesita un «reset» método que puede golpear a un número desconocido de funciones o módulos es tener un contador global de cómo muchas veces que el método reset ha sido llamado, y luego que cada función o módulo de incluir código como:

    extern unsigned long global_reset_count; 
    
    void do_something(int lo que sea) 
    { 
    estática ... esto, que el otro, etc. ...; 
    static unsigned long my_reset_count; 
    
    si (my_reset_count != global_reset_count) 
    { 
    my_reset_count = global_reset_count; 
    ... inicializar esto, que el otro, etc ... 
    } 
    } 
    

    En algunos multi-threading contextos, si la inicialización de las variables estáticas puede depender de algunas variables globales, uno puede reemplazar el «si» con un «mientras»; en tal caso; barreras de memoria también puede ser necesario en tal caso, aunque los requisitos exactos varían dependiendo del entorno de funcionamiento.

    También, un modelo alternativo que puede ser útil en sistemas embebidos sería tener un modules_initialized variable global que se pone a 0 por el mundial método reset, y luego que cada módulo comienza con algo como:

     if (!atomic_bit_test_and_set32(&modules_initialized, FOOBOZZ_MODULE_ID)) 
    { 
    ... Inicializar el módulo de FOOBOZZ ... 
    } 
    

    Esto requeriría que hay más de 32 ID del módulo, y requieren que sean asignados de forma exclusiva, de alguna manera, pero en algunos sistemas se puede controlar bastante bien. Por ejemplo, un enlazador puede definir una «sección de datos» de la dirección de 0 a 31 de un espacio de direcciones independiente de cualquier otro; si cada módulo declara un solo byte variable dentro de ese espacio de direcciones, el vinculador podría generar la dirección de esas variables.

    OriginalEl autor supercat

  5. 0

    que usted puede construir su función de tal manera que si se llama con cero parámetros, a continuación, se restablecerá su interior las variables estáticas

    aquí está un ejemplo :

    int foo(matrix *A = NULL, int colnum = 0, int rownum = 0)
    {
       static int whichColumn;
       static int *v; //vector of length A->nrows 
    
       if (A == NULL){
        FREE(v);
        whichColumn = 0;
       } 
       //do other things
    }

    Que en realidad sólo tiene que llamar a la función para restablecer como este:

    foo();  //internal values would then be reset

    Asegúrese de que todos sus parámetros a la función tiene valores predeterminados, por ejemplo, si se pasa un opcional, asegúrese de que tiene = boost::ninguno como valor predeterminado

    OriginalEl autor serup

Dejar respuesta

Please enter your comment!
Please enter your name here