我有一个程序将目录放在链表中并打印出来。链表被搞砸了具有相同数据的所有节点。例如,我有一个文件夹"测试'它有3个子文件夹" Good One"," Jump"," Sunday"。输出是 - >周日周日周日。
在调试时,插入函数的第一次迭代,第一个节点中的变量数据被设置为" Good One"。根节点指针的地址被传递回main。 最初,startptr-> data =" Good One"。执行readdir后,dir-> d_name是" Jump"。但是startptr->数据变为" Jump"。同样的情况发生在第3天和周日#34;并且列表中的所有节点都有data =" Sunday"。
不确定为什么会这样。感谢任何帮助。 这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
/* self-referential structure */
struct listNode {
char *data; /* each listNode contains a character */
struct listNode *nextPtr; /* pointer to next node */
}; /* end structure listNode */
typedef struct listNode ListNode; /* synonym for struct listNode */
typedef ListNode *ListNodePtr; /* synonym for ListNode* */
/* prototypes */
void insert( ListNodePtr *sPtr, char *value );
void printList( ListNodePtr currentPtr );
int main( void )
{
ListNodePtr startPtr = NULL; /* initially there are no nodes */
DIR *d = NULL;
struct dirent *dir = NULL;
d = opendir ("/Users/Satish/Documents/Test");
if (d != NULL)
{
while ((dir = readdir (d)) != NULL)
{
/*printf("%s\n", dir->d_name);*/
if ( (strcmp(dir->d_name, ".") == 0) || (strcmp(dir->d_name, "..") == 0) )
{
}
else
insert( &startPtr, dir->d_name ); /* insert item in list */
}
closedir (d);
}
else
printf("%s/n", "Couldn't open the directory");
printList( startPtr );
printf( "End of run.\n" );
return 0; /* indicates successful termination */
} /* end main */
/* Insert a new value into the list in sorted order */
void insert( ListNodePtr *sPtr, char *value )
{
ListNodePtr newPtr = NULL; /* pointer to new node */
ListNodePtr previousPtr = NULL; /*pointer to previous node in list */
ListNodePtr currentPtr = NULL; /* pointer to current node in list */
printf("%s\n", value);
newPtr = malloc( sizeof( ListNode ) ); /* create node */
if ( newPtr != NULL ) /* is space available */
{
newPtr->data = value; /* place value in node */
newPtr->nextPtr = NULL; /* node does not link to another node */
previousPtr = NULL;
currentPtr = *sPtr;
if (currentPtr == NULL)
*sPtr = newPtr;
else
{
while ( currentPtr != NULL )
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = NULL;
}
}
else
{
printf( "%c not inserted. No memory available.\n", value );
} /* end else */
} /* end function insert */
/* Print the list */
void printList( ListNodePtr currentPtr )
{
/* if list is empty */
if ( currentPtr == NULL ) {
printf( "List is empty.\n\n" );
} /* end if */
else {
printf( "The list is:\n" );
/* while not the end of the list */
while ( currentPtr != NULL ) {
printf( "%s\n", currentPtr->data );
currentPtr = currentPtr->nextPtr;
} /* end while */
printf( "NULL\n\n" );
} /* end else */
} /* end function printList */
输出为:
列表是: 星期日 星期日 周日
答案 0 :(得分:3)
在insert
函数中,您指向所有元素的相同地址,您必须分配内存来存储名称。请参阅代码第57行并添加:
newPtr = malloc( sizeof( ListNode ) ); /* create node */
if ( newPtr != NULL ) /* is space available */
{
char *val=malloc((strlen(value)+1)*1);
strcpy(val,value);
newPtr->data = val; /* place value in node */
newPtr->nextPtr = NULL;
.
.
.
答案 1 :(得分:0)
在insert
中,您可以像这样分配字符串:
newPtr->data = value;
这将存储dirent
结构中字符串的引用。这将始终是指向同一缓冲区的指针,但每次创建链接时缓冲区将具有不同的内容。当你打印它时,该缓冲区当然会有最后一个条目的内容。 (当dirent
结构超出范围时,指针变为陈旧:它将指向无效数据。但是在代码中并非如此。)
要存储实际值,您必须创建副本。 Thzat副本需要存储,您必须分配:
newPtr->data = malloc(strlen(value) + 1);
strcpy(newPtr->data, value);
每个malloc
都需要相应的free
,因此在销毁列表时不要忘记释放字符串的内存。