删除基于struct的数组中的最后一个单元格

时间:2015-01-12 22:37:04

标签: c arrays struct cell free

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct address
{
char name[80],addr[50],city[50],country[30];
int code;
} *list,*list2;

int main()
{
int epilogi,n=1,x,i;
char temp[2],temp2[2];
list=malloc(n*sizeof(struct address));
printf("Lista taxidromikon dieuthinseon\n");
printf("1. Eisagogi stoixeion\n");
printf("2. Diagrafi stoixeion\n");
printf("3. Emfanisi listas\n");
printf("4. Eksodos\n\n");
printf("Epilekste dinontas dinontas ena arithmo apo to 1 eos to 4\n");
while (epilogi!=4)
{
if (epilogi==1)
{
while (strcmp("n",temp))
{
printf("Dose onomateponimo, dieuthinsi, poli, xora kai taxidromiko kodika\n");
fgets(list[n-1].name,80,stdin);
fgets(list[n-1].addr,50,stdin);
fgets(list[n-1].city,50,stdin);
fgets(list[n-1].country,30,stdin);
scanf("%[^\n]%d%*c", &list[n-1].code);
printf("------------------------------------\n");
printf("Thelete na eisagete allo stoixeio?(Pliktrologiste y gia nai n gia oxi)\n");
fgets(temp,2,stdin);
printf("\n");
if (strcmp("n",temp))
{
n=n+1;
list=realloc(list,n*sizeof(struct address));
}
}
}
strcpy(temp,"y");
if (epilogi==2) 
{
while (strcmp("n",temp2))
{
printf("Dose taxidromiko kodika\n");
scanf("%s", &x);
for (i=0;i<n;i++)
{
if (list[i].code=x)
{
list2=malloc((n-1)*sizeof(struct address));
strcpy(list[i].name,list[n-1].name);
strcpy(list[i].addr,list[n-1].addr);
strcpy(list[i].city,list[n-1].city);
strcpy(list[i].country,list[n-1].country);
list[i].code=list[n-1].code;
}
}
for (i=0;i<n-1;i++)
{
strcpy(list2[i].name,list[i].name);
strcpy(list2[i].addr,list[i].addr);
strcpy(list2[i].city,list[i].city);
strcpy(list2[i].country,list[i].country);
list2[i].code=list[i].code;
}
free(list);
list=malloc((n-1)*sizeof(struct address));
for (i=0;i<n-1;i++)
{
strcpy(list[i].name,list2[i].name);
strcpy(list[i].addr,list2[i].addr);
strcpy(list[i].city,list2[i].city);
strcpy(list[i].country,list2[i].country);
list[i].code=list2[i].code;
}
free(list2);
n=n-1;
printf("Thelete na diagrapsete allo stoixeio?(Pliktrologiste y gia nai n gia oxi)\n");
scanf("%s", &temp2);
}
}
strcpy(temp2,"y");
if (epilogi==3)
{
for (i=0;i<n;i++)
{
printf("%s\t%s\t%s\t%s\t%d\n", list[i].name, list[i].country, list[i].city, list[i].addr, list[i].code);
}
}
printf("Dose nea epilogi\n");
scanf("%d", &epilogi);
}
return 0;
}

所以这是一个为用户提供3个选项的程序 1)输入元素 2)删除元素 3)显示元素列表 4)退出程序 好吧,我的问题是在第二个选项。在那里,我将要求删除的元素与结构地址列表的最后一个单元格中的元素交换。然后我尝试使用free()函数删除最后一个单元格(实际上它是5个单元格,因为它是一个基于结构的数组),但这似乎不起作用。它不编译。

[edit]所以我更新了我的代码,现在我尝试通过将整个“list”复制到“list2”来删除最后一个单元格,除了最后一个单元格。然后我释放了列表并用少一个单元格(n-1)将它们重新定位,将它们从list2复制回来并释放list2。那么代码编译但结果不是我所期望的。最后一个单元格已成功删除,但由于某种原因,一个特定的列表输入被复制到所有其他单元格。因此,当我转到选项3(假设我的列表中有3个元素并且我删除了一个)时,会出现2个元素,但它们是相同的。有线索吗?

2 个答案:

答案 0 :(得分:0)

当我将free(list[n-1]);更改为free(list);时为我编译的代码。 list[n-1]不是可以解除分配的数组 - 它是数组中的结构。在这种情况下,您只能解除分配整个数组。

顺便说一下,您应该在问题中添加标签C,以便其他人更容易看到您的问题。

答案 1 :(得分:0)

一些问题:

你没有初始化temp [2]但你有一个while循环

while (strcmp("n",temp))

所以这可能会也可能不会起作用,具体取决于程序开始时temp中的垃圾。


这个稍微复杂的表达

scanf("%[^\n]%d%*c", &list[n-1].code);

可以这样写成

char codeBuf[10];
fgets( codeBuf, sizeof(codeBuf), stdin);
list[n-1].code = atoi(codeBuf);

fgets(temp,2,stdin);
printf("\n");
if (strcmp("n",temp))
{ ... }

表达式(strcmp("n",temp))永远不会成为真,因为fgets()在缓冲区中包含\n。您需要删除\n或仅进行字符比较if (temp[0] == 'n')


现在问题

为了删除数组中的元素,您需要创建一个新缓冲区并复制除要删除的元素之外的所有元素,或者将数组中的后续条目向前移动一步,覆盖要删除的元素,您还需要跟踪缓冲区的原始大小,并且只有在添加的分配数超过分配时才重新分配。在数组条目上执行此操作将导致未定义的行为,即分配数组时获得的地址

list=malloc(n*sizeof(struct address));

是您可以免费使用的唯一地址。

通常当出现这种问题时,使用双链表来处理条目会更容易 - 在列表中插入和释放更简单的IMO。

相关问题