TransWikia.com

Acces Violation en C y otros problemas

Stack Overflow en español Asked on January 12, 2021

En la aplicación que estoy desarrollando tiene que haber una serie de librerías, pues bien, en determinadas funciones que manipulan estructuras de datos me salta un error -1073741819 0xC0000005 (lo he buscado y ponía que correspondía con el tema de Acces Violation). Adjunto un ejemplo de una de las funciones que presentan esta problemática:

void borraFiltro(FILTROS* filtros, int posicion){
    int i;

    if(filtros == NULL || filtros->p == NULL){//Falla porque cuando no hay filtros establecidos detecta que si los hay
        printf("ERROR: no existen filtros establecidos.nn");
    }else{
        if(filtros->num < posicion){//Falla
            printf("ERROR: %d excede al numero total de filtros(%d).nn", posicion, filtros->num);
        }else if(posicion < 1){
          printf("ERROR: %d debe ser un numero entre 1 y el numero total de filtros(%d).nn", posicion, filtros->num);
        }else{

            FILTRO* puntero1 = filtros->p;

            if(puntero1->next == NULL){
                eliminaFiltro(puntero1);
                filtros->p = NULL;
            }else{
                FILTRO* puntero2 = puntero1->next;
                for(i=1;i<posicion && puntero1 != NULL;i++){//Verificacion fin de lista
                    puntero2 = puntero1; //Salva el puntero anterior
                    puntero1 = puntero1->next;
                }
                if(puntero1 == NULL){//validación extra por si la lista está cortada
                    eliminaFiltro(puntero2);
                }else{
                    puntero2->next = puntero1->next;//AQUI SALTA EL FALLO
                    if(filtros->p == puntero1){ //Veficar si el elemento a eliminar es el primero
                        filtros->p = puntero1->next;
                    }
                    eliminaFiltro(puntero1);
                }
            }
        }
    }
}

Definicion de la estructura de datos llamada filtro:

typedef struct fil {
    COLUMNA * pCol;         //puntero a la columna
    OPERANDO operador;      //operación a realizar
    char *valor;            //valor a aplicar
    struct fil *next;   //puntero al siguiente filtro
} FILTRO;

Funcion encargada de generar una ED filtro:

FILTRO* generaFiltro(COLUMNA* columna, char c_operador[], char valor[]){
    FILTRO* filtro = (FILTRO*) malloc(sizeof (FILTRO));

    filtro->valor = (char*)malloc((strlen(valor)+1)*sizeof(char));
    strcpy(filtro->valor, valor);

    filtro->pCol = (COLUMNA*) malloc(sizeof (COLUMNA));
    filtro->pCol = columna;

    if(strcmp(c_operador,"==") == 0){
       filtro->operador = IGUAL;
    }else if(strcmp(c_operador,"!=") == 0){
       filtro->operador = DISTINTO;
    }else if(strcmp(c_operador,">") == 0){
        filtro->operador = MENOR;
    }else if(strcmp(c_operador,">=") == 0){
        filtro->operador = MENORIGUAL;
    }else if(strcmp(c_operador,"<") == 0){
        filtro->operador = MAYOR;
    }else if(strcmp(c_operador,"<=") == 0){
        filtro->operador = MAYORIGUAL;
    }

    filtro->next = (FILTRO*) malloc(sizeof (FILTRO));
    filtro->next = NULL;

    return filtro;
}

Definicion de la ED filtros:

typedef struct {
    int num;    //numero de filtros contenidos en la lista
    FILTRO *p;  //puntero al primer filtro
}FILTROS;

Funcion encargada de generar el ED filtros:

FILTROS* generaFiltros(){
    FILTROS* filtros = (FILTROS*) calloc(1,sizeof (FILTROS));
    filtros->p = (FILTRO*) calloc(1,sizeof (FILTRO));
    filtros->p = NULL;
    return filtros;
}

En cuanto a los problemas menores, son los comentados en la primera pieza de código: falla la evaluación de filtros->num < posicion. Además, pese a las correcciones realizadas en base a algunas de las respuestas. La verificacion de si existen o no filtros falla.

2 Answers

revisa lo siguiente:

  • en la inicialización de FILTROS, p se inicialize con NULL
  • verifica el valor de la variable filtros
  if(filtros == NULL || filtros->p == NULL){
    printf("ERROR: no existen filtros establecidos.nn");
  }
  • Revisa el código que recorre los FILTROS, parece incorrecto pues faltan validaciones, prueba con este:
FILTRO* puntero1 = filtros->p;

if(puntero1->next == NULL){//revisar
    eliminaFiltro(puntero1);
    filtros->p = NULL; //Borrar la referencia de p
}else{
{
    FILTRO* puntero2 = puntero1;
    for(i=1; i<posicion && puntero1 != NULL; i++){ //Verificas el fin de la lista
        puntero2 = puntero1; //Salva el puntero anterior
        puntero1 = puntero1->next; //Te mueves al siguiente
    }
    if(puntero1 == NULL){//validación extra por si la lista está cortada
        eliminaFiltro(puntero2);
    }else{
        puntero2->next = puntero1->next;
        if(filtros->p == puntero1){ //Veficar si el elemento a eliminar es el primero
            filtros->p = puntero1->next;
        }
        eliminaFiltro(puntero1);
    }
}

Answered by LeoLopez on January 12, 2021

Suena a que el último elemento de tu lista no tiene el next a NULL.

Ten en cuenta que al pedir memoria (el malloc) el valor de next no tiene porqué estar a NULL automáticamente.

También es posible (aunque menos probable) de que inicialices el next a NULL y luego en alguna operación de memoria haya un buffer overflow y escribas donde no toca, afectando al valor de next.

Por último, noto que haces

           if(puntero2->next == NULL){
                eliminaFiltro(puntero2);
            }else{

con lo cual supongo que liberas puntero2, pero no veo que asignes NULL a puntero1->next. Así que puntero1->next apuntaría a una posición no NULL que sin embargo ya ha sido liberada. No creo que esto te cause el problema que describes (si fuera eso el error te saldría en el free) pero es un ejemplo de lo delicada que es la gestión dinámica de memoria.

En todo caso tendrás que ir depurando todo tu código poco a poco, la gestión de memoria en C/C++ se presta a muchos fallos a no ser que seas muy organizado.

Answered by SJuan76 on January 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP