我试图通过编写一个程序来学习C语言的基础知识,该程序提示用户输入整数,然后将这些值存储在一个链表中。如果输入值为-128
或更小,则current
节点被设置为NULL
,提示符结束。然后,该程序遍历链表并计算输入值的平均值。然而,列表的计数器总是比预期多一个元素,从而导致不正确的平均值,尽管我在添加每个值和递增计数器之前显式指定了NULL
检查。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
struct record {
int temperature;
struct record *next;
};
// Keep hold of the first record for iterating --v
struct record *first = NULL;
first = (struct record *)malloc(sizeof(struct record));
// Keep hold of the current record used in the while loop --v
struct record *current = first;
while (true) {
// Get user input --v
int temp;
printf("Enter measurement: ");
scanf("%d", &temp);
// If input is less than -128, end the loop --v
if (temp <= -128) {
current = NULL;
break;
}
// Record the temperature --v
current->temperature = temp;
// Allocate memory for the next record --v
current->next = (struct record *)malloc(sizeof(struct record));
// The next now becomes the current because we are done with the current --v
current = current->next;
printf("Next record created!\n");
}
// Calculate average --v
current = first;
double sum = 0.;
int count = 0;
// As long as the record is not NULL --v
while (current != NULL) {
sum += current->temperature;
count++;
printf("%d %d\n", count, current->temperature);
// Move to the next record --v
current = current->next;
}
printf("\nAverage of the list values: %.1f", sum / count);
}
这是正确的行为吗?C中是否有一些我不知道的机制?
我添加了一些调试行,以便跟踪计数器以及相应的记录,并发现current
属性看起来并不为NULL,尽管我显式地将其设置为NULL。
Enter measurement: 22
Next record created!
Enter measurement: 22
Next record created!
Enter measurement: 22
Next record created!
Enter measurement: -128
1 22
2 22
3 22
4 0
Average of the list values: 16.5
我确实尝试过使用free(current)
来释放current
指针的内存,但结果并不好,因为temperature
只保存了一个随机数。
1条答案
按热度按时间6jjcrrmo1#
问题在于指针
current
和current->next
是两个不同的指针,它们占用不同的内存区。current
是局部变量,而current->next
是动态分配节点的数据成员。在这份声明中
你把指针
current->next
的值设为指针current
的值,所以这两个指针的值相同。但是在这个if语句中
只有指针
current
发生了变化,指针"previous"current->next
保持不变,即局部变量current
发生了变化,但动态分配节点的数据成员next
没有发生变化,指向一个数据成员未初始化的动态分配节点。分配内存时采用的方法如下
并且它的地址被分配给指针
current->next
,然后在循环中试图将指针设置为NULL
,无论如何都会导致内存泄漏。您应该重新设计代码的逻辑。最简单的方法是使用指针对指针,例如
在while循环之外,你需要为一个辅助指针使用另一个名字。
请注意这一点--当不再需要该列表时,您需要释放所有分配的内存。