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.
revisa lo siguiente:
FILTROS
, p se inicialize con NULLfiltros
if(filtros == NULL || filtros->p == NULL){
printf("ERROR: no existen filtros establecidos.nn");
}
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP