c语言 - 你能告诉我为什么我从链表中选择随机字符串的函数不起作用吗?



我正在为一个项目构建一个程序。该项目的需求之一是一个从我的3000字链接列表中随机选择一个节点的函数。

我试图通过创建一个函数来实现这一点,该函数生成一个从0到2999的随机数。在此之后,我创建了另一个函数,该函数遵循从头部开始并移动到下一个节点(随机数(的for循环。

我的随机数生成器工作正常,但我的chooseRand()函数不正常。

请帮忙,随机数生成器和chooseRand()函数是main上面的最后两个函数。另外,我的代码有点乱,对不起。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int nodeNum;
int chances;
char* secret;

/*Node of linked list*/
typedef struct node {
char *data;
struct node *next;
} node;
node *start = NULL;
node *current;
/*Void function to print list*/
void printList(struct node *node)
{
while (node != NULL) {
printf("%s ", node->data);
node = node->next;
}
}
/*Appending nodes to linked list*/
void add(char *line) {
node *temp = malloc(sizeof(node));
temp->data = strdup(line);
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}

void readfile(char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL) {
exit(1);
}
char buffer[512];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
add(buffer);
}
fclose(file);
}
node *listSearch(node* start, char *nodeSearched){
node *p;
for (p = start; p != NULL; p = p->next)
if (strcmp(p->data, nodeSearched) == 0)
printf("%s", p->data);
return NULL;
}
node *letterSearch(node* start, int i){
node *p;
for (p = start; p != NULL; p = p->next)
if (strlen(p->data) == i)
{
printf("n %s", p->data);
free(p);
p = NULL;
}
return NULL;
}
void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
for(n = 0; n != nodeNum; n++)
{
p = p->next;
}
printf("%s", p->data);
}
void randNum(int lower, int upper)
{
srand(time(0));
nodeNum = (rand() % (upper - lower + 1)) + lower;
}
int main(){
randNum(0, 2999);
chooseRand(start);


return 0;
}

正如其他人所说,问题是您还没有初始化链表,因为您遇到了分段错误。因此,除了首先初始化列表外,您还必须在chooseRand函数的实现中引入检查,以检查如果您到达列表的末尾,而没有达到所需的索引,则停止执行foor循环,否则您可能会面临分段错误。

改进chooseRand的实现,以防止在链表为空或随机生成的nodeNum比列表最后一项的索引((更大时出现分段错误

void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
if(p == NULL){
printf("The list is empty!");
return;
}
// Also, we must stop the iteration, if we are going to pass the end of the list, you don't want a segmentation fault because trying to access a NULL pointer:
for(n = 0; n != nodeNum && p->next != NULL; n++)
{
p = p->next;
}
// If p == NULL, the list was not big enough to grab an item in the `nodeNum` index:
printf("%s", (n != nodeNum) ? "Not found!" : p->data);
}

初始化链接列表,其中包含磁盘上某个文件的内容:

int main(){
randNum(0, 2999);

// Fill the linked list with the content of a file in disk, calling your method:
char fileName[] = "PutYourFileNameHere.txt";
readfile(fileName);
chooseRand(start);
return 0;
}

您必须进行另一个修复,即在方法letterSearch的实现中释放结构的指针字段data所占用的内存。在if语句中,您正在取消分配由p指针保持的内存,但您没有取消分配分配给指针p->data的内存,这将导致内存泄漏。当您在函数add中,使用对函数strdup(line)的调用结果初始化p->data时,此函数所做的是在堆中分配足够的内存,将line参数所指向的缓冲区复制到其中,并向您返回一个指向新分配的内存的指针,该指针存储在p.data字段中;一个指针,当你完成它时,你应该释放它,否则你的程序将有潜在的内存泄漏。因此,我将修改您的函数letterSearch如下:

node *letterSearch(node* start, int i){
node *p;
for (p = start; p != NULL; p = p->next)
if (strlen(p->data) == i)
{
printf("n %s", p->data);
// Free p->data before free p:
free(p->data);
free(p);
p = NULL;
}
return NULL;
}

参考文献:strdup

相关内容

  • 没有找到相关文章

最新更新