C:程序即使在释放结构后仍打印垃圾文本
C: program prints garbage text even after structs are freed
我有一个具有以下结构的程序:
typedef struct slide
{
int number;
int maxX;
int y;
int r, g, b;
struct line *first;
} slide;
typedef struct line {
char content[256]; // number subject to change
int r, g, b;
struct line *prev;
struct line *next;
} line;
使用以下代码创建这些结构的实例:
slide* createSlideArray(int s) {
slide* slides = malloc(sizeof(struct slide)*s);
return slides;
}
line *nextLine(line *prev) {
line *n = malloc(sizeof(line));
n->prev = prev;
prev->next = n;
return n;
}
最后是在程序循环结束后和打开新文件之前释放结构的代码:
void freeLines(line *l) {
line *next;
while(l) {
next = l->next;
free(l);
l = next;
}
}
主要内容:
int i;
for (i=0;i<slideCount;i++) {
freeLines(slides[i].first); // works through next till NULL
}
free(slides);
如您所见,slide 结构的一个实例包含一个 "first" 行结构,该行结构是一个双重 linked 列表。该行的内容被读到屏幕上(使用 ncurses)
虽然在程序循环中用户可以键入命令:open filename
来打开一个新文件,但这是我的问题所在。
应释放此幻灯片和线条。当循环再次开始时,它将打开一个新文件,创建幻灯片和线条,并将它们用作内容。但是,内容部分充满了垃圾文本。我很确定这个问题在结构中,以及它是如何免费的。但是,我没有看到我做错了。
编辑:我应该说清楚,在程序的第一次迭代中,文本是完美的,只有当我尝试解析一个新文件时,才会出现垃圾文本,而且它非常均匀(出现在每行的前面,相同的字符)
如果有影响的话,我在 Ubuntu。
这里是一个link项目:DSS
通过阅读您 post 中的代码,我可以发现一些明显的问题。我不能明确地说这些是否是你的问题的原因,因为你的 post 中的代码不是一个可编译的示例,我没有深入研究你的链接项目。
你的 nextLine 函数:
您忘记设置 n->next。
你也忽略了设置下一个节点的prev指针,如果有的话。 ( prev->next->prev 如果 prev->next != NULL )。
您当前的设计阻止您使用此函数来设置列表中的第一个节点。它也没有显示您打算如何创建该节点。
此函数不允许您将节点添加到列表的开头。
您的 createSlideArray 函数:
此函数不会初始化它创建的幻灯片。必须初始化这些幻灯片实例。在这里这样做似乎是明智的,但您可能有充分的理由在其他地方这样做。在任何一种情况下,初始化 slideObject.first 成员都是至关重要的。如果没有这个,您将无法判断幻灯片是否有行列表,并且您的 freeLines 函数将失败,因为它将垃圾作为其参数传递。
注:
实现双向链表的另一种方法是使用 "head node",它始终存在并链接到列表中的第一个和最后一个节点。这简化了一些问题,但改变了其他问题。有兴趣的可以研究一下。
我可以通过简单地正确调用 memset
来解决问题。对于线路,我能够执行以下操作:
memset(l, 0, sizeof(*l));
获取 l 指针值的大小而不是指针本身的大小很重要,否则您将无法正确释放内存。这是我面临的问题。
我有一个具有以下结构的程序:
typedef struct slide
{
int number;
int maxX;
int y;
int r, g, b;
struct line *first;
} slide;
typedef struct line {
char content[256]; // number subject to change
int r, g, b;
struct line *prev;
struct line *next;
} line;
使用以下代码创建这些结构的实例:
slide* createSlideArray(int s) {
slide* slides = malloc(sizeof(struct slide)*s);
return slides;
}
line *nextLine(line *prev) {
line *n = malloc(sizeof(line));
n->prev = prev;
prev->next = n;
return n;
}
最后是在程序循环结束后和打开新文件之前释放结构的代码:
void freeLines(line *l) {
line *next;
while(l) {
next = l->next;
free(l);
l = next;
}
}
主要内容:
int i;
for (i=0;i<slideCount;i++) {
freeLines(slides[i].first); // works through next till NULL
}
free(slides);
如您所见,slide 结构的一个实例包含一个 "first" 行结构,该行结构是一个双重 linked 列表。该行的内容被读到屏幕上(使用 ncurses)
虽然在程序循环中用户可以键入命令:open filename
来打开一个新文件,但这是我的问题所在。
应释放此幻灯片和线条。当循环再次开始时,它将打开一个新文件,创建幻灯片和线条,并将它们用作内容。但是,内容部分充满了垃圾文本。我很确定这个问题在结构中,以及它是如何免费的。但是,我没有看到我做错了。
编辑:我应该说清楚,在程序的第一次迭代中,文本是完美的,只有当我尝试解析一个新文件时,才会出现垃圾文本,而且它非常均匀(出现在每行的前面,相同的字符)
如果有影响的话,我在 Ubuntu。
这里是一个link项目:DSS
通过阅读您 post 中的代码,我可以发现一些明显的问题。我不能明确地说这些是否是你的问题的原因,因为你的 post 中的代码不是一个可编译的示例,我没有深入研究你的链接项目。
你的 nextLine 函数:
您忘记设置 n->next。
你也忽略了设置下一个节点的prev指针,如果有的话。 ( prev->next->prev 如果 prev->next != NULL )。
您当前的设计阻止您使用此函数来设置列表中的第一个节点。它也没有显示您打算如何创建该节点。
此函数不允许您将节点添加到列表的开头。
您的 createSlideArray 函数:
此函数不会初始化它创建的幻灯片。必须初始化这些幻灯片实例。在这里这样做似乎是明智的,但您可能有充分的理由在其他地方这样做。在任何一种情况下,初始化 slideObject.first 成员都是至关重要的。如果没有这个,您将无法判断幻灯片是否有行列表,并且您的 freeLines 函数将失败,因为它将垃圾作为其参数传递。
注:
实现双向链表的另一种方法是使用 "head node",它始终存在并链接到列表中的第一个和最后一个节点。这简化了一些问题,但改变了其他问题。有兴趣的可以研究一下。
我可以通过简单地正确调用 memset
来解决问题。对于线路,我能够执行以下操作:
memset(l, 0, sizeof(*l));
获取 l 指针值的大小而不是指针本身的大小很重要,否则您将无法正确释放内存。这是我面临的问题。