C malloc valgrind - 在我的单链表实现中未初始化的内存
C malloc valgrind - uninitialised memory in my singly linked list implementation
我尝试在c 中实现一个单向链表。我希望能够使用列表的多个实例,并且我想在主函数中创建列表。这就是为什么我选择以我的方式实现它。
代码工作得很好,但我担心是因为 valgrind 创建的输出。我还尝试在嵌入式系统的项目中使用代码,但出现了奇怪的错误。
valgrind 输出为:
starting...
==3570== Conditional jump or move depends on uninitialised value(s)
==3570== at 0x100000E8E: push_cfront (in ./map_test)
==3570== by 0x100000D4F: main (in ./map_test)
==3570== Uninitialised value was created by a heap allocation
==3570== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3570== by 0x100000E80: push_cfront (in ./map_test)
==3570== by 0x100000D4F: main (in ./map_test)
==3570==
...finished
它还告诉我,我失去了一个街区。释放它哪里出错了
==3570== LEAK SUMMARY:
==3570== definitely lost: 16 bytes in 1 blocks
==3570== indirectly lost: 0 bytes in 0 blocks
==3570== possibly lost: 2,064 bytes in 1 blocks
==3570== still reachable: 0 bytes in 0 blocks
==3570== suppressed: 24,525 bytes in 186 blocks
请指点一下我哪里做错了。
test.c:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "command_list.h"
int main() {
printf("starting...\n");
Clist * command_list = malloc(sizeof(Clist));
if (command_list == NULL) printf("Malloc Failed\n");
command_list->head = NULL;
//push_cback(command_list, 0);
push_cfront(command_list,1);
free_clist(command_list);
free(command_list);
printf("\n...finished\n");
return 0;
}
command_list.h:
#ifndef __COMMAND_LIST_H
#define __COMMAND_LIST_H
typedef struct cnode {
uint8_t command;
struct cnode * next;
} Cnode;
typedef struct clist {
Cnode * head;
} Clist;
void push_cback(Clist * list, uint8_t command);
void push_cfront(Clist * list, uint8_t command);
void free_clist(Clist * list);
#endif
command_list.c
void push_cfront(Clist * list, uint8_t command){
Cnode * new_node;
new_node = malloc(sizeof(Cnode));
if (new_node->next == NULL) {
return;
}
new_node->command = command;
new_node->next = list->head;
list->head = new_node;
}
void free_clist(Clist * list){
if (list->head == NULL){
return; //already empty
}
Cnode * current = list->head;
while (current->next != NULL){
Cnode* temp = current->next;
free(current);
current = temp;
}
free(current);
list->head = NULL;
}
当您检查它的值时,new_node->next
未初始化。你不需要那个。
如果您寻找 malloc
失败,请为函数设置 return 代码并在调用时检查它。
在此之前,不需要 push_cfront
中的 if
分支。
...或者您想检查 list->head
?
push_cfront
中的这段代码也有问题
new_node = malloc(sizeof(Cnode));
if (new_node->next == NULL) {
return;
}
这是未定义的行为,因为 new_node
内存未初始化。您可能想检查 if (new_node == NULL)
以查看是否实际分配了内存。
你有一些问题。您正在检查 new_node->next
(malloc 内存中未初始化的数据)而不是 new_node
(malloc 的 return 值)。至少在我的电脑上,这也会导致内存不被释放,因为偶然 new_node->next
为空,所以你 return 而没有释放 new_node
。另外,如果你想支持推到链表的后面,你应该考虑循环链表,因为它允许该操作而不必遍历整个链表。
最后,一些提示:您使用 valgrind 很好,但是如果您使用 -g
编译以启用调试符号,那么 valgrind 会告诉您行号,这会更有帮助。此外,当我制作链表时,我喜欢对某些操作使用虚拟头节点,以避免出现空列表或单例列表的特殊情况。对于插入排序链表,该技术如下所示:
int sorted_insert(Clist *list, char new_command){
Cnode _head = {NULL, list->head}, *head = &_head, *prev = head, *tmp;//head is an auto dummy node obviating null checks.
int ord = -1;//If there are no existing nodes, newObj would be less than all objects.
while(prev->next && (ord = (int)newObj - prev->next->command)) > 0){//Iterate by prev->next not curr to use only one pointer.
prev = prev->next;//Looping while there is a next node and its data compares less than new_command.
}
if((!ord) || !(tmp = malloc(sizeof(Cnode))){//newObj is already in the list or allocation failed.
return 0;
}
*tmp = (Cnode){.next=prev->next, .command=new_command};
prev->next = tmp;
list->head = head->next;//un- add head which is then deallocated by stack frame cleanup.
return 1;
}
我尝试在c 中实现一个单向链表。我希望能够使用列表的多个实例,并且我想在主函数中创建列表。这就是为什么我选择以我的方式实现它。
代码工作得很好,但我担心是因为 valgrind 创建的输出。我还尝试在嵌入式系统的项目中使用代码,但出现了奇怪的错误。
valgrind 输出为:
starting...
==3570== Conditional jump or move depends on uninitialised value(s)
==3570== at 0x100000E8E: push_cfront (in ./map_test)
==3570== by 0x100000D4F: main (in ./map_test)
==3570== Uninitialised value was created by a heap allocation
==3570== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3570== by 0x100000E80: push_cfront (in ./map_test)
==3570== by 0x100000D4F: main (in ./map_test)
==3570==
...finished
它还告诉我,我失去了一个街区。释放它哪里出错了
==3570== LEAK SUMMARY:
==3570== definitely lost: 16 bytes in 1 blocks
==3570== indirectly lost: 0 bytes in 0 blocks
==3570== possibly lost: 2,064 bytes in 1 blocks
==3570== still reachable: 0 bytes in 0 blocks
==3570== suppressed: 24,525 bytes in 186 blocks
请指点一下我哪里做错了。
test.c:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "command_list.h"
int main() {
printf("starting...\n");
Clist * command_list = malloc(sizeof(Clist));
if (command_list == NULL) printf("Malloc Failed\n");
command_list->head = NULL;
//push_cback(command_list, 0);
push_cfront(command_list,1);
free_clist(command_list);
free(command_list);
printf("\n...finished\n");
return 0;
}
command_list.h:
#ifndef __COMMAND_LIST_H
#define __COMMAND_LIST_H
typedef struct cnode {
uint8_t command;
struct cnode * next;
} Cnode;
typedef struct clist {
Cnode * head;
} Clist;
void push_cback(Clist * list, uint8_t command);
void push_cfront(Clist * list, uint8_t command);
void free_clist(Clist * list);
#endif
command_list.c
void push_cfront(Clist * list, uint8_t command){
Cnode * new_node;
new_node = malloc(sizeof(Cnode));
if (new_node->next == NULL) {
return;
}
new_node->command = command;
new_node->next = list->head;
list->head = new_node;
}
void free_clist(Clist * list){
if (list->head == NULL){
return; //already empty
}
Cnode * current = list->head;
while (current->next != NULL){
Cnode* temp = current->next;
free(current);
current = temp;
}
free(current);
list->head = NULL;
}
当您检查它的值时,new_node->next
未初始化。你不需要那个。
如果您寻找 malloc
失败,请为函数设置 return 代码并在调用时检查它。
在此之前,不需要 push_cfront
中的 if
分支。
...或者您想检查 list->head
?
push_cfront
new_node = malloc(sizeof(Cnode));
if (new_node->next == NULL) {
return;
}
这是未定义的行为,因为 new_node
内存未初始化。您可能想检查 if (new_node == NULL)
以查看是否实际分配了内存。
你有一些问题。您正在检查 new_node->next
(malloc 内存中未初始化的数据)而不是 new_node
(malloc 的 return 值)。至少在我的电脑上,这也会导致内存不被释放,因为偶然 new_node->next
为空,所以你 return 而没有释放 new_node
。另外,如果你想支持推到链表的后面,你应该考虑循环链表,因为它允许该操作而不必遍历整个链表。
最后,一些提示:您使用 valgrind 很好,但是如果您使用 -g
编译以启用调试符号,那么 valgrind 会告诉您行号,这会更有帮助。此外,当我制作链表时,我喜欢对某些操作使用虚拟头节点,以避免出现空列表或单例列表的特殊情况。对于插入排序链表,该技术如下所示:
int sorted_insert(Clist *list, char new_command){
Cnode _head = {NULL, list->head}, *head = &_head, *prev = head, *tmp;//head is an auto dummy node obviating null checks.
int ord = -1;//If there are no existing nodes, newObj would be less than all objects.
while(prev->next && (ord = (int)newObj - prev->next->command)) > 0){//Iterate by prev->next not curr to use only one pointer.
prev = prev->next;//Looping while there is a next node and its data compares less than new_command.
}
if((!ord) || !(tmp = malloc(sizeof(Cnode))){//newObj is already in the list or allocation failed.
return 0;
}
*tmp = (Cnode){.next=prev->next, .command=new_command};
prev->next = tmp;
list->head = head->next;//un- add head which is then deallocated by stack frame cleanup.
return 1;
}