我有一个应用程序,它接受多个命令行参数,在它接受目标主机文件的参数中,将对其执行某些操作。
173.194.40.225
157.55.152.112
200.49.185.230
195.95.178.226
98.158.27.203
在每一行上是目标的IP地址,我使用以下函数遍历文件;
// Open file read line by line to Linked List
ListNode* file(char *file, char *option)
{
FILE *ptr_file;
char buffer[1000];
char *destination;
ListNode *linelist;
// Create an empty line list
linelist = NULL;
// Open a file
if(strcmp(option, "r") == 0)
{
ptr_file = fopen(file, option);
if(!ptr_file)
{
printf("Can\'t open file\n\n");
exit(0);
}
}
else
{
printf("File operation not implemented\n\n");
exit(0);
}
// Traverse through the file
while (fgets(buffer, LINE_MAX, ptr_file) != NULL)
{
printf("Line: %s\n", buffer);
// Add line to Linked List
linelist = addtoList(linelist, buffer);
printf("---------------------------------------\n\n");
}
printList(linelist);
// Close the file
fclose(ptr_file);
// Return a pointer to linelist
return linelist;
}
该函数应该传回一个指针,该指针指向可以在单独的套接字函数中使用的目标IP地址的链接列表。链接列表的设计如下;
// Define node structure
struct listnode
{
char *data;
struct listnode *next;
};
// Define node as a type
typedef struct listnode ListNode;
// Add to List
ListNode* addtoList( ListNode *List, char *data );
在file()函数使用while循环遍历传递的文件并且fgets()将每一行加载到缓冲区之后,缓冲区被传递给addtoList()函数,该函数接受两个变量,一个指向链接列表的指针和指向char的指针,实际上只是传递文件的每一行。该函数旨在添加到传递列表的末尾。
该功能的工作原理如下;
1)创建ListNode&类型的临时指针。使用malloc()
分配内存2)检查malloc()是否返回NULL,如果确实如此,则通知用户,否则用传递的数据填充临时ListNode
3)如果传递给函数的ListNode为NULL,只需将临时ListNode分配给传递的NULL ListNode并返回列表
4)如果传递给函数的ListNode不为NULL,并且传递的ListNode下一个值为NULL,则将临时ListNode分配给ListNode下一个值并返回列表
5)如果传递给函数的ListNode不为NULL,并且传递的ListNode下一个值不为NULL,则创建指向列表开头的指针的副本。使用while循环遍历列表,直到我们到达最后一个NULL的ListNode。将临时ListNode分配给NULL ListNode
功能如下;
// Add to List
ListNode* addtoList(ListNode *List, char *data)
{
printf("Adding: %s\n", data);
// Create pointer to allocated memory the size of a ListNode
ListNode* temp = (ListNode*)malloc( sizeof( ListNode ) );
// Check malloc didn't return NULL
if(temp == NULL)
{
printf( "Can\'t allocate memory for temp, failed to allocate the requested block of memory, a null pointer is returned\n\n" );
exit(0);
}
else
{
printf("Memory allocated for temp, filling allocated memory\n\n");
// Fill the allocated memory where data is a pointer to data
temp->data = data;
temp->next = NULL;
printf("Allocated memory for temp filled with data\n\n");
}
printf("temp->data = %s\n\n", temp->data);
int size = countList(List);
printf("List size: %i\n\n", size);
if(List == NULL)
{
// If computer can't allocate memory let us know
printf( "List is empty\n\n" );
List = temp;
printf( "List is now temp\n\n" );
return List;
}
else
if(List != NULL && List->next == NULL)
{
printf("List isn\'t empty and List->next is NULL\n\n");
List->next = temp;
return List;
}
else
if(List != NULL && List->next != NULL)
{
printf("List isn\'t empty and List->next is not NULL\n\n");
ListNode* Head = List;
while(Head != NULL)
{
printf("List->next data: %s List->next pointer: %p\n\n", Head->data, Head->next);
Head = Head->next;
}
if(Head == NULL)
{
printf("Head equals null\n");
//problem here
Head->next = temp;
}
return List;
}
}
我的问题位于if(Head == NULL)条件语句中addtoList()函数的最末端,临时ListNode分配给Head-> next;
if(Head == NULL)
{
printf("Head equals null\n");
//problem here
Head->next = temp;
}
应用程序的输出如下;
######################################
Line: 173.194.40.225
Adding: 173.194.40.225
Memory allocated for temp, filling allocated memory
Allocated memory for temp filled with data
temp->data = 173.194.40.225
List size: 1
List is empty
List is now temp
---------------------------------------
Line: 157.55.152.112
Adding: 157.55.152.112
Memory allocated for temp, filling allocated memory
Allocated memory for temp filled with data
temp->data = 157.55.152.112
List size: 2
List isn't empty and List->next is NULL
---------------------------------------
Line: 200.49.185.230
Adding: 200.49.185.230
Memory allocated for temp, filling allocated memory
Allocated memory for temp filled with data
temp->data = 200.49.185.230
List size: 3
List isn't empty and List->next is not NULL
List->next data: 200.49.185.230
List->next pointer: 0x8592180
List->next data: 200.49.185.230
List->next pointer: (nil)
Head equals null
Segmentation fault
我遇到的问题是将临时ListNode分配到listnode结构的NULL ListNode中。
非常感谢任何帮助...
修改
所以我的addtoList()函数现在在molbdnilo& s&迭戈的推荐;
// Add to end of List
ListNode* addtoList(ListNode *List, char *data)
{
char* data_ptr = data; // Create a pointer to passed data
char* bkup_copy = NULL; // Create a null pointer for backing up passed data
bkup_copy = copyString(data_ptr); // Create a backup of data
// Create pointer to allocated memory the size of a ListNode
ListNode* temp = (ListNode*)malloc( sizeof( ListNode ) );
// Check malloc didn't return NULL
if(temp == NULL)
{
printf("Can\'t allocate memory for temp, failed to allocate the requested block of memory, a null pointer returned\n\n" );
exit(0);
}
else
{
// Fill the allocated memory where data is a pointer to data
temp->data = bkup_copy;
temp->next = NULL;
}
if(List == NULL)
{
List = temp;
return List;
}
else
if(List != NULL && List->next == NULL)
{
List->next = temp;
return List;
}
else
if (List != NULL && List->next != NULL)
{
// Create a copy of pointer to passed list
ListNode* Head = List;
// Traverse through the list until last item
while(Head->next != NULL)
{
Head = Head->next;
}
// Assign temp to the last list item next
Head->next = temp;
return List;
}
else
{
printf("Unknown state of List\n\n");
exit(0);
}
}
使用新的copyString()函数,它只返回字符串的副本,如下所示;
char* copyString(char* data)
{
char* data_ptr = data; // Create a pointer to passed data
int orig_str_size = 0; // Create an int to hold passed data size
char* bkup_copy = NULL; // Create a null pointer to backup passed data
int bkup_index = 0; // Create a index variable for traversal of passed data
int length;
// Count the number of characters in data_ptr
while (*data_ptr++ != '\0')
{
orig_str_size++;
}
// Dynamically allocate space for a backup copy of data
bkup_copy = (char*)malloc((orig_str_size+1) * sizeof(char));
// Check malloc didn't return NULL
if(bkup_copy == NULL)
{
printf("Can\'t allocate memory for bkup_copy, failed to allocate the requested block of memory, a null pointer returned\n\n" );
exit(0);
}
else // Copy data to separate allocated memory
{
// Place the '\0' character at the end of the backup string.
bkup_copy[orig_str_size] = '\0';
// Assign the pointer to data to the first pointer position in data
data_ptr = &data[0];
// The backup string is not the '\0' character copy data to bkup_copy
while (*data_ptr != '\0'){ bkup_copy[bkup_index++] = *data_ptr++; }
}
return bkup_copy;
}
现在按预期工作......如果有人能看到该代码的任何问题,请告诉我,以便我现在可以修复它...
答案 0 :(得分:5)
问题在于您无法取消引用NULL
,并且您已确定Head
NULL
。
您需要提前停止遍历,以便将新节点链接到列表中的最后一个节点。
// Find the last node - the node with NULL as its 'next'
while (Head->next != NULL)
{
Head = Head->next;
}
// 'Head' is now the last node.
// Replace the NULL at the end of the list with the new node.
Head->next = temp;