我已经创建了以下代码:在C中实现链接列表。
为了测试它,我创建了一个标签结构,其中包含一个string和int变量。
在上传到这里之前,代码是很好的注释和测试。
我想听听你对此的看法,我也不确定free和malloc是否运行良好(我使用了DrMemory,它没有出现错误,但是内存是一个“漏”的东西(lol))。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*label */
/*The label is managed by lnode, which contains the address-string(8-bits)
and the label-name. */
typedef struct label{
int address; /* The address number. */
char* name; /* The name of the label. */
}label;
/*Label implementation*/
/*Create label object*/
label* createLabel(int address, char* name)
{
int len;
label* newlabel;
if(NULL == name){
return NULL;
}
len = strlen(name)+1;
newlabel = (label*)malloc(sizeof(label));
if(NULL == (newlabel->name = (char*)malloc(sizeof(char)*len))){
return NULL;
}
/*copy name to new-label name*/
strcpy(newlabel->name, name);
/*set address in newlabel*/
newlabel->address = address;
return(newlabel);
}
/*delete label object*/
void deleteLabel(void* ob ){
label *lbl;
if(NULL == ob){
return;
}
lbl = (label*)ob;
/*delete the name*/
free(lbl->name);
/*delete the Label object*/
free(lbl);
}
/*Print Label-objects --> for Testing*/
/*Allocate a string and fill with label data*/
void printLabel(void* ob){
label* obl= (label*)ob;
printf("%s%d, label: %-10s, ","address: ",obl->address,obl->name);
}
/*gnode*/
/*generic-node struct to be used in a generic list*/
struct gnode{
void *value; /*pointer to generic-node */
struct gnode* next; /*pointer to next node */
}typedef gnode;
/*createGnode*/
/*create a gnode to be added to a generic-list*/
gnode* createGnode( void* value, gnode* next){
gnode* newnode=NULL;
if(NULL == value){
return NULL;
}
if (NULL == (newnode = (gnode*)malloc(sizeof(gnode)))) {
return NULL;
}
/*add the value*/
newnode->value = value;
/*set next value to be NULL --> All added gnode are
added at the end of the list and become the last node */
newnode->next = next;
return(newnode);
}
/*freeGnode*/
/*free the allocated gnode, using a function to delete the pointed value */
void freeGnode(gnode* nodetodelete, void (*deletefunc)( void*)){
if(NULL == nodetodelete){
return;
}
/*delete the value, pointed by void* value */
deletefunc(nodetodelete->value);
/*free the allocated gnode*/
free(nodetodelete);
}
/*insertGnode --> insert gnode to list*/
int insertGnode(gnode** glist, gnode* newnode)
{
gnode* curr; /*pointer to current node in list*/
if(NULL == newnode){
return -1; /*no item to insert*/
}
/*Empty list*/
else if(NULL == *glist){
*glist = newnode;
return 1;
}
/*add newnode in last place in list*/
/*Get to last node*/
for( curr = *glist; curr->next != NULL; curr = curr->next);
/*Add the newnode as last node*/
curr->next = newnode;
/*return Success*/
return 1;
}
/*deleteGenericList*/
/*Parse each generic-node and delete */
void deleteGenericList(gnode* glist, void (*deleteValue)(void*))
{
gnode* curr=NULL;
gnode* next;
if(NULL == glist){
return;
}
/*Delete each generic-node*/
for(curr = glist; curr != NULL; ){
next = curr->next;
deleteValue(curr->value); /*free the value objext */
free(curr); /*free current generic-node */
curr = next;
}
/*Set glist to point at NULL*/
glist = NULL;
}/*End deleteGenericList*/
/*writeGlist --> write Gnode to an open-file*/
void writeGenericList(FILE* fp, gnode* glist, void (*writeValue)(FILE*, void*))
{
gnode* curr=NULL; /*curr node in the generic-list*/
/*check that all arguments are present*/
if( (NULL == fp)||(NULL==glist)||(NULL==writeValue) ){
return;
}
/*use the writeValue function to write the gnode into the file*/
for(curr = glist; curr != NULL; curr=curr->next){
writeValue(fp, curr->value);
}
}/*End writeGenericList*/
/*For testing...*/
void printGlist(gnode* glist, void (*printValue)(void*)){
gnode *curr;
if(NULL == glist){
return;
}
for (curr = glist; curr != NULL; curr = curr->next){
printValue(curr->value);
}
}
void printGlistOLD(gnode* glist, void (*printValue)(void*)){
gnode *curr;
if(NULL == glist){
return;
}
printf("%-20s\n", "GenericList: top-To-Bottom");
for (curr = glist; curr != NULL; curr = curr->next){
printValue(curr->value);
}
}
int main(int argc, char const *argv[])
{
printf("start\n");
label *label1 = createLabel(100,"hello world");
label *label2 = createLabel(101,"a");
label *label3 = createLabel(102,"b");
label *label4 = createLabel(100,"c");
label *label5 = createLabel(103,"d");
label *label6 = createLabel(102,"e");
gnode* g1 = createGnode(label1,NULL);
gnode* g2 = createGnode(label2,NULL);
gnode* g3 = createGnode(label3,NULL);
gnode* g4 = createGnode(label4,NULL);
gnode* g6 = createGnode(label6,NULL);
gnode* g5 = createGnode(label5,g6);
printf("%d\n",insertGnode(&g1,g2));
printf("%d\n",insertGnode(&g1,g3));
printf("%d\n",insertGnode(&g1,g4));
printf("%d\n",insertGnode(&g1,g5));
printGlistOLD(g1,printLabel);
deleteGenericList(g1,deleteLabel);
return 0;
}谢谢!
发布于 2017-08-21 06:48:45
strcpy(newlabel->name, name);的目的。insertGnode不插入,而是添加到列表中。考虑改名。您似乎并不担心列表中节点的顺序。考虑对新节点进行前缀,如int add_gnode( gnode* * glist,gnode* newnode) { if (newnode == NULL) {rever-1;}newnode>next= *glist;*glist= newnode;返回1;}这种方法有两个好处:printGlist应该用适当的参数调用writeGenericList。genericList结构以deletefunc、writeValue等为成员。发布于 2017-08-21 09:16:03
void *:newlabel =( label* )malloc(sizeof(标签));应是: newlabel =malloc(sizeof(标签));以及void printLabel( void ){ label* obl = (label*)ob;应该是:void(void* ob) {标签* obl = ob;create_label中有一个潜在的内存泄漏: newlabel = malloc (sizeof(标签));//不要强制转换malloc if (空== (新标签->name=malloc(sizeof(Char)*len)){返回空;//泄漏先前分配的标签}createGnode插入节点位于第一个位置,而insertGnode将它添加到最后一个位置。freeGnode无条件地释放节点及其内容,如果您删除列表中的节点,则=>中的任何链接都可能断开,至少在注释中显示不能从列表中删除节点。deleteGenericList(gnode* glist, void(*deleteValue)(void*))中,最后一条指令(glist = NULL;)是无操作的,因为它只设置将在下一行超出作用域的函数中的局部值。https://codereview.stackexchange.com/questions/173452
复制相似问题