【发布时间】:2018-03-23 14:06:28
【问题描述】:
我的代码包含在一个应用程序中,该应用程序通过控制台一个客户端 (clientes) 接收并将其添加到使用 malloc 创建的数组中。在我们可以删除这个客户之后。我们还可以添加一个新的旅行 (viajes) 并将其删除(过程类似于代码中显示的过程)。
如前所述,我正在尝试删除使用 malloc 创建的结构数组的最后一项。我将向您展示代码(如何添加新的clientes 以及如何尝试删除它)。还说我得到的错误在产生错误的行中被注释,所以我认为它更直观。还说代码是 MCVE,所以只会运行复制代码。我的应用代码是:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
// DEFINE STRUCTS
struct viaje {
char *identificador;
char *ciudadDestino;
char *hotel;
int numeroNoches;
char *tipoTransporte;
float precioAlojamiento;
float precioDesplazamiento;
};
struct cliente {
char *dni;
char *nombre;
char *apellidos;
char *direccion;
int totalViajes;
struct viaje *viajes;
};
int main(){
// Variables
int i = 0;
int totalClientes = 0;
char dni[255];
char nombre[255];
char apellidos[255];
char direccion[255];
// Init array of struct cliente (in var clientes)
struct cliente *clientes = (struct cliente *)malloc(0);
printf("Input number of elements of struct clientes: ");
scanf("%i", &totalClientes);
fflush(stdin);
// ADDING NEW ELEMENTS INTO CLIENTES
for (i = 0; i < totalClientes; i++) {
// Receive parameters
printf("Input NIF: ");
gets(dni);
fflush(stdin);
printf("Input NAME: ");
gets(nombre);
fflush(stdin);
printf("Input SURNAME: ");
gets(apellidos);
fflush(stdin);
printf("Input ADDRESS: ");
gets(direccion);
fflush(stdin);
// Create memory for his child (MAX_TAM_* are #define int)
clientes = (struct cliente *)realloc(clientes, (i+1)*sizeof(struct cliente));
clientes[i].dni = (char *)malloc(200*sizeof(char));
clientes[i].nombre = (char *)malloc(200*sizeof(char));
clientes[i].apellidos = (char *)malloc(200*sizeof(char));
clientes[i].direccion = (char *)malloc(200*sizeof(char));
clientes[i].viajes = (struct viaje *)malloc(0); // Init clientes[i].viajes to 0 as previously done with clientes
// Adding received element
strcpy(clientes[i].dni, dni);
strcpy(clientes[i].nombre, nombre);
strcpy(clientes[i].apellidos, apellidos);
strcpy(clientes[i].direccion, direccion);
/* DANGER - ERROR HERE */
clientes[i].totalViajes = 0; // HERE I GET A NOT EXPECTED BEHAVIOR - int is not added to clientes[i].totalViajes - Receive NULL
// New element added sucessfully
}
// SHOW ELEMENTS CREATED
for (i = 0; i < totalClientes; i++) {
printf("\n");
printf("%i.\n", i);
printf("NIF: %s\n", clientes[i].dni);
printf("NAME: %s\n", clientes[i].nombre);
printf("SURNAME: %s\n", clientes[i].apellidos);
printf("ADDRESS: %s\n", clientes[i].direccion);
printf("TRAVELS_COUNT: %s\n", clientes[i].totalViajes);
printf("\n");
}
// DELETING AN ELEMENT OF CLIENTES
int posCliente = 0;
printf("Input position of struct clientes that you wanna delete: ");
// posCliente is the position (inside the array) of cliente we wanna remove
scanf("%i", &posCliente);
fflush(stdin);
// Rewind one position array clientes since cliente we want to remove
for (i = posCliente; i < totalClientes-1; i++) {
// Rewind one element array clientes
clientes[i] = clientes[i+1];
}
//freeing memory of this element (now, the element is the last of the array, we have moved it into last position with previously for)
free(clientes[totalClientes].dni);
free(clientes[totalClientes].nombre);
free(clientes[totalClientes].apellidos);
free(clientes[totalClientes].direccion);
clientes[totalClientes].totalViajes = 0;
// Remove / free memory of the element deleted
/* DANGER - ERROR HERE */
//free(clientes[totalClientes]); // HERE I GET AN ERROR: `error: incompatible type for argument 1 of 'free'`
// Now totalClientes is one less (we have deleted one element)
totalClientes--;
// Resize array clientes. It must have one less element (now totalClientes is totalClientes-1)
/* DANGER - ERROR HERE */
//clientes = (struct cliente *)realloc(clientes, (totalClientes)*sizeof(struct cliente)); // HERE I DO NOT GET AN ERROR BUT PROGRAM CRASH
// SHOW ELEMENTS AFTER DELETING
/* DANGER - ERROR HERE */
// if the max legnth is totalClientes+1 we can see that the last element removed with free cointinues existing, so free is not freeing memory well
for (i = 0; i < totalClientes; i++) {
printf("\n");
printf("%i.\n", i);
printf("NIF: %s\n", clientes[i].dni);
printf("NAME: %s\n", clientes[i].nombre);
printf("SURNAME: %s\n", clientes[i].apellidos);
printf("ADDRESS: %s\n", clientes[i].direccion);
printf("TRAVELS_COUNT: %s\n", clientes[i].totalViajes);
printf("\n");
}
}
【问题讨论】:
-
不要尝试释放最后一个元素,只需将数组向下重新分配一个。
-
@MartinJames 但需要提前释放内存删除最后一个元素,不是吗?但是,当我尝试调整数组大小时,程序崩溃没有错误,所以我不知道发生了什么
-
全局变量
i是个坏主意,尤其是在单功能程序中。当它被用作main()中的循环控制变量时更是如此。 -
是的,我知道,这只是我的代码的一个示例功能。在我的原始代码中
i是本地的,不是全局的 -
注意Using
fflush(stdin)的约束。
标签: c arrays struct malloc free