Ваша проблема (ну, одна из них), кажется, лежит здесь:
lista = (Localidade**) realloc( lista, (posicao)*sizeof(Localidade*));
lista = lista_aux;
Это не копирует все в lista_aux
в lista
, это просто изменяетlista
указатель на указатель на данные lista_aux
(перезаписывает память, которую вы только что перераспределили).
Если вы затем освобождаете эти данные, ваш указатель остается указанным на освобожденную память.вам не нужно копировать память, если вы создали новый массив, вам нужно просто освободить оригинал и вернуть сделанную копию:
free (lista);
lista = lista_aux;
Есть лучший способ сделать то, чтоВы пытаетесь сделать это на месте.Это более простая форма, которая просто использует исходный и целевой индекс для удаления нежелательных элементов.
Обычно исходный и целевой адреса будут идентичны, так что массив не изменится, но при обнаружении удаляемого элемента источникувеличивается без пункта назначения (после освобождения данных для нежелательного элемента, конечно).
Я также изменил его, чтобы он также возвращал вам новый размер.Вот полная программа, набор тестов и все:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct localidade {
char nome[31];
float local[3];
} Localidade;
static void dump ( int sz, Localidade **lista) {
int i;
printf ("Size = %d\n", sz);
for (i = 0; i < sz; i++)
printf (" [%s]\n", lista[i]->nome);
}
Localidade **remover (
Localidade **lista,
char end_remover[],
int posicao,
int *new_posicao)
{
int sidx, didx;
// Maintain separate source and destination indexes.
sidx = didx = 0;
while (sidx < posicao) {
// If need to remove, just increment source after freeing.
if (stricmp (end_remover, lista[sidx]->nome) == 0) {
free (lista[sidx]);
lista[sidx++] = NULL;
continue;
}
// Otherwise transfer and increment both indexes.
lista[didx++] = lista[sidx++];
}
*new_posicao = didx;
if (sidx != didx)
lista = realloc (lista, (*new_posicao) * sizeof(Localidade*));
return lista;
}
int main (void) {
int sz;
Localidade **x = malloc (3 * sizeof(Localidade*));
x[0] = malloc (sizeof(Localidade));
x[1] = malloc (sizeof(Localidade));
x[2] = malloc (sizeof(Localidade));
sz = 3;
strcpy (x[0]->nome, "PaxDiablo");
strcpy (x[1]->nome, "Adriano");
strcpy (x[2]->nome, "Kate Bush");
dump (sz, x);
x = remover (x, "AdRiAnO", sz, &sz);
dump (sz, x);
return 0;
}
, который выдает, как ожидается:
Size = 3
[PaxDiablo]
[Adriano]
[Kate Bush]
Size = 2
[PaxDiablo]
[Kate Bush]