我在C中创建了一个名为'remover'的函数,用于删除数组'lista'的结构。此功能调整'lista'的大小。问题是我试图打印'lista'的元素,但它打印出奇怪的东西。 当我没有释放'lista_aux'时,程序正常运行。为什么会这样?
typedef struct localidade{
char nome[31];
float local[3];
}Localidade;
Localidade** remover(Localidade** lista, char end_remover[], int posicao){
int i, j;
int pos_remover;
char nome_aux[31];
Localidade** lista_aux;
lista_aux = (Localidade**) malloc((posicao) * sizeof(Localidade*));
if( lista_aux == NULL){
printf("Erro na alocacao de memoria!\n");
exit(-1);
}
for( i = 0; i < posicao; i++){
lista_aux[i] = (Localidade*) malloc(sizeof(Localidade));
if( lista_aux[i] == NULL){
printf("Erro na alocacao de memoria!\n");
exit(-1);
}
}
for( i = 0; end_remover[i]; i++ ){
end_remover[i] = toupper( end_remover[i] );
}
for( i = 1; i < posicao; i++){
strcpy( nome_aux, lista[i]->nome);
for( j = 0; nome_aux[j]; j++){
nome_aux[j] = toupper( nome_aux[j] );
}
if( !(strcmp( end_remover, nome_aux)) ){
pos_remover = i;
break;
}
else if( i == posicao ){
printf("Endereco nao cadastrado.\n");
}
}
for( i = 0; i < posicao; i++){
if( i < pos_remover ){
lista_aux[i] = lista[i];
}
else{
lista_aux[i] = lista[i + 1];
}
//printf("***%s\n", lista_aux[i]->nome);
}
lista = (Localidade**) realloc( lista, (posicao)*sizeof(Localidade*));
lista = lista_aux;
//printf("*****%s\n", lista[1]->nome);
/*for( i = 0; i < posicao; i++ ){
printf("***%s\n", lista[i]->nome);
}
for( i = 0; i < posicao; i++ ){
printf("*****%s\n", lista_aux[i]->nome);
}*/
/*for( i = 0; i < posicao; i++){
free( lista_aux[i] );
}
free( lista_aux );*/
return lista;
}
答案 0 :(得分:1)
你的问题(好吧,其中一个)似乎在这里:
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]
答案 1 :(得分:1)
如果你释放lista_aux,你的代码将返回一个无效(释放)指向调用者的指针,因为这行:
lista = lista_aux;
您的代码还有其他问题(取决于您如何调用它,您可能有内存泄漏,对于初学者而言)我建议您查看您的算法以从“lista”中删除条目。一个建议是列表的已知大小(或以NULL结尾的列表),并使用memmove()而不是手动复制。