我在C中实现了一个基本的BST。虽然我在使用Memcheck时遇到错误,但似乎我的插入功能正常工作,如:
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A0D: bst_insert (bst.c:65)
==7839== by 0x4007A5: main (bst-test.c:22)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A2B: bst_insert (bst.c:61)
==7839== by 0x4007B2: main (bst-test.c:23)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A0D: bst_insert (bst.c:65)
==7839== by 0x400A0D: bst_insert (bst.c:65)
==7839== by 0x4007BF: main (bst-test.c:24)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A2B: bst_insert (bst.c:61)
==7839== by 0x400A0D: bst_insert (bst.c:65)
==7839== by 0x4007CC: main (bst-test.c:25)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A0D: bst_insert (bst.c:65)
==7839== by 0x400A2B: bst_insert (bst.c:61)
==7839== by 0x4007D9: main (bst-test.c:26)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009EF: bst_insert (bst.c:45)
==7839== by 0x400A2B: bst_insert (bst.c:61)
==7839== by 0x400A2B: bst_insert (bst.c:61)
==7839== by 0x4007E6: main (bst-test.c:27)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009AF: bst_inorder (bst.c:30)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009D0: bst_inorder (bst.c:30)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009AF: bst_inorder (bst.c:30)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009D0: bst_inorder (bst.c:30)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009AF: bst_inorder (bst.c:30)
==7839== by 0x4009C3: bst_inorder (bst.c:35)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x4009D0: bst_inorder (bst.c:30)
==7839== by 0x400807: main (bst-test.c:29)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400A7F: bst_preorder (bst.c:77)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400AA0: bst_preorder (bst.c:77)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400A7F: bst_preorder (bst.c:77)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400AA0: bst_preorder (bst.c:77)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400A7F: bst_preorder (bst.c:77)
==7839== by 0x400A98: bst_preorder (bst.c:84)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400AA0: bst_preorder (bst.c:77)
==7839== by 0x400825: main (bst-test.c:31)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400AD4: bst_search (bst.c:91)
==7839== by 0x400B38: dosearch (bst-test.c:10)
==7839== by 0x400850: main (bst-test.c:34)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400AD4: bst_search (bst.c:91)
==7839== by 0x400B38: dosearch (bst-test.c:10)
==7839== by 0x40085D: main (bst-test.c:35)
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400dfe is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400d9f is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400da3 is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400de5 is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400da1 is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400da5 is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Invalid free() / delete / delete[] / realloc()
==7839== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7839== by 0x400980: bst_free (bst.c:21)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839== Address 0x400da7 is not stack'd, malloc'd or (recently) free'd
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400989: bst_free (bst.c:22)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839== Conditional jump or move depends on uninitialised value(s)
==7839== at 0x400977: bst_free (bst.c:17)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x400992: bst_free (bst.c:23)
==7839== by 0x40087F: main (bst-test.c:38)
==7839==
==7839==
==7839== HEAP SUMMARY:
==7839== in use at exit: 224 bytes in 14 blocks
==7839== total heap usage: 14 allocs, 7 frees, 224 bytes allocated
==7839==
==7839== LEAK SUMMARY:
==7839== definitely lost: 80 bytes in 8 blocks
==7839== indirectly lost: 144 bytes in 6 blocks
==7839== possibly lost: 0 bytes in 0 blocks
==7839== still reachable: 0 bytes in 0 blocks
==7839== suppressed: 0 bytes in 0 blocks
==7839== Rerun with --leak-check=full to see details of leaked memory
==7839==
==7839== For counts of detected and suppressed errors, rerun with: -v
==7839== Use --track-origins=yes to see where uninitialised values come from
==7839== ERROR SUMMARY: 39 errors from 35 contexts (suppressed: 0 from 0)
这是我的实施:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mylib.h"
#include "bst.h"
struct bstnode {
char *key;
bst left;
bst right;
};
bst bst_free(bst b) {
if (b == NULL) {
return b;
}
free(b->key);
bst_free(b->left);
bst_free(b->right);
return b;
}
void bst_inorder(bst b, void f(char *str)) {
if (NULL == b) {
return;
}
bst_inorder(b->left, f);
f(b->key);
bst_inorder(b->right, f);
}
bst bst_insert(bst b, char *str) {
if (b == NULL) {
bst result = emalloc(sizeof *result);
result->key = str;
return result;
}
if (strcmp(b->key, str) == 0) {
return b;
}
if (strcmp(b->key, str) < 0) {
b->right = bst_insert(b->right, str);
return b;
}
b->left = bst_insert(b->left, str);
return b;
}
bst bst_new() {
return NULL;
}
void bst_preorder(bst b, void f(char *str)) {
if (NULL == b) {
return;
}
f(b->key);
bst_preorder(b->left, f);
bst_preorder(b->right, f);
}
int bst_search(bst b, char *str) {
if (NULL == b) {
return 0;
}
if (strcmp(b->key, str) == 0) {
return 1;
}
if (strcmp(b->key, str) < 0) {
return bst_search(b->right, str);
}
return bst_search(b->left, str);
}
我有另一个文件只测试它,我的输出是按预期的,但我不太清楚为什么 我收到这些消息。这是我用来检查我的BST的文件:
#include <stdio.h>
#include <stdlib.h>
#include "bst.h"
void print_key(char *key) {
printf("%s\n", key);
}
void dosearch(bst b, char *key) {
if (bst_search(b, key) == 0) {
printf("%s -- not found\n", key);
} else {
printf("%s -- found\n", key);
}
}
int main(void) {
bst b = bst_new();
printf("inserting d,b,f,a,c,e,g\n");
b = bst_insert(b, "d");
b = bst_insert(b, "b");
b = bst_insert(b, "f");
b = bst_insert(b, "a");
b = bst_insert(b, "c");
b = bst_insert(b, "e");
b = bst_insert(b, "g");
printf("inorder traversal\n");
bst_inorder(b, print_key);
printf("preorder traversal\n");
bst_preorder(b, print_key);
printf("searching\n");
dosearch(b, "f");
dosearch(b, "o");
dosearch(b, "x");
dosearch(b, "e");
dosearch(b, "d");
bst_free(b);
return EXIT_SUCCESS;
}
答案 0 :(得分:2)
虽然我不知道您使用的这个emalloc
函数,但普通malloc
不会初始化它分配的内存,这意味着left
和right
指针不会被初始化。使用这些未初始化的指针会导致undefined behavior。
解决方案?只需在分配后将这些指针设置为NULL
。
答案 1 :(得分:0)
我猜您将'bst'定义如下:
typedef struct bstnode *bst;
我认为bst_insert()存在问题 你只为bst_node的指针变量分配内存。
bst result = emalloc(sizeof *result);
你必须为bst_node本身和bst_node的密钥分配内存 以下代码是解决问题的部分原因。
bst bst_insert(bst b, char *str) {
if (b == NULL) {
{
bst result = emalloc(sizeof(struct bstnode));
result->left = null;
result->right = null;
result->key = emalloc(strlen(str) + 1);
strcpy(result->key, str);
return result;
}
.....
}