代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct node {
char* identifier;
char* expression;
struct node* next;
} node;
void add(node** database, char* _identifier, char* _expression, int * size) {
node* tmp = (node*) malloc (sizeof(node));
tmp->identifier = _identifier;
tmp->expression = _expression;
tmp->next = *database;
*database = tmp;
(*size)++;
printf("Added: %s : %s\n", _identifier, _expression); fflush(NULL);
}
void show(node* database, int size) {
if (database == NULL) {
printf("Database empty\n");
}
else {
node* tmp = database;
printf("Identifier list (%d):\n", size); fflush(NULL);
while (tmp != NULL) {
printf("%s : \"%s\" \n", tmp->identifier, tmp->expression);fflush(NULL);
tmp = tmp->next;
}
}
}
int main() {
node* database = NULL;
int size = 0;
add(&database, "a1", "abc", &size);
add(&database, "a2", "def", &size);
add(&database, "a3", "ghi", &size);
char identifier[20];
char expression[1000];
int i;
for (i = 0; i<3; i++) {
scanf("%s %s", identifier, expression);
add(&database, identifier, expression, &size);
}
show(database, size);
printf ("Bye!");
return 0;
}
手动调用时,“添加”功能运行良好,但在循环内部无效,数据从标准输入读取。以下是一次运行的结果:
Added: a1 : abc
Added: a2 : def
Added: a3 : ghi
a4 mno
Added: a4 : mno
a5 ghi
Added: a5 : ghi
a6 kml
Added: a6 : kml
Identifier list (6):
a6 : "kml"
a6 : "kml"
a6 : "kml"
a3 : "ghi"
a2 : "def"
a1 : "abc"
Bye!
正如您所见,节点a1,a2,a3已正确添加到列表中。但是,正确添加到列表后,a4和a5在添加a6后更改为全部“a6”。 我花了一天时间,但我无法理解。任何人
答案 0 :(得分:2)
你的问题是他们都指向同一个指针:identifier
。 (也expression
)。 (前3个添加指向静态初始化的单独const char*
。)
要解决此问题,您需要为添加的每个新元素动态分配空间(例如使用malloc
),并在删除它们时释放它们(例如使用free
)。
e.g:
void add(node** database, char* _identifier, char* _expression, int * size) {
node* tmp = (node*) malloc (sizeof(node));
tmp->identifier = (char *)malloc(strlen(_identifier));
strcpy(tmp->identifier, _identifier);
tmp->expression = (char *)malloc(strlen(_expression));
strcpy(tmp->expression, _expression);
tmp->next = *database;
*database = tmp;
(*size)++;
printf("Added: %s : %s\n", _identifier, _expression); fflush(NULL);
}
您必须确保在某些时候相应地释放这些资源,否则您将发生内存泄漏。
答案 1 :(得分:2)
嗯...因为你存储的是指针而不是字符串的副本?
每次都在main中存储'identifier'和'expression'的地址,因此链表上的所有3个项目都指向相同的数据。