【发布时间】:2015-08-16 09:26:36
【问题描述】:
我有一个应用程序,它接受多个命令行参数,在参数中,它接受一个目标主机文件,将对其执行某些操作。
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 next value为NULL,则将临时ListNode赋给ListNode next value并返回列表
5) 如果传递给函数的 ListNode 不为 NULL,并且传递的 ListNode next 值不为 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 和 Diego 的建议如下;
// 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;
}
它现在按预期工作...如果有人可以看到该代码有任何问题,请告诉我,以便我现在可以修复它...
【问题讨论】:
-
另外,永远不要转换
malloc返回的指针。 -
temp->data = data:这里需要复制数据;否则,所有节点都将指向同一个缓冲区 -
它被标记为C&C++,因为有些程序员用C和C++编程,更多的是引起有能力的人的注意...
-
如果你想引起懂c的人的注意,即使他们也懂c++,你也可以用c标签引起他们的注意。如果您需要帮助形成 c++ 程序员,一个明智的解决方案是将您的所有代码替换为
std::list。 -
@xxwatcherxx 我很高兴能为您服务 :)
标签: c list pointers data-structures linked-list