2010-02-11 66 views
0

我正在Visual Studio 2010 Ultimate Beta(Win 7)上开发C89。我不认为我正确使用malloc()。我是C新手,请原谅初学者问题。C89:访问冲突读取0x00(与malloc的难度)

我的程序的目标是使用树计算**argv中单词的出现次数。

hist.c

#include "tree.h" 
#include <stdlib.h> 

int main(int argc, char *argv[]) { 
    unsigned int i; 
    struct tree *tree; 
    tree = new_tree(); 

    for (i = 1; i < argc; i++) { 
     tree_add(tree, argv[i]); 
    } 

    tree_dump(tree); 
    tree_free(tree); 

    return 0; 
} 

tree_add.c:

#include "tree.h" 
#include <stdlib.h> 
#include <string.h> 

struct tree *tree_add(struct tree *tree, char *value) { 
    if (tree == NULL) { 
     tree = new_tree(); 
     tree->value = value; 
     tree->count = 0; 
    } 
    else if (tree->value == NULL) { 
     tree->value = value; 
    } 
    else if (tree->value == value) { 
     tree->count++; 
    } 
    else if (strcmp(value, tree->value) < 0) { 
     tree_add(tree->left, value); 
    } 
    else if (strcmp(value, tree->value) > 0) { 
     tree_add(tree->right, value); 
    } 
} 

struct tree *new_tree() { 
    struct tree * tree; 
    tree = malloc(sizeof *tree); 
    tree->left = NULL; 
    tree->right = NULL; 
    tree->value = NULL; 
    tree->count = 0; 
    return tree; 
} 

我得到的错误是:

0000005:访问冲突读取 位置00000000。

我在网上查看,看起来这个错误是由于试图访问不正确分配的内存引起的。那么我做错了什么?

已更新反映评论的代码。现在我有一个新问题。当value == "x"tree->value == "x"

else if (tree->value == value) { 

在调试器中,我看到tree->value0x00553373 "x" char *,而value0x00553375 "x" char *这种情况是不正常。十六进制值在最后一位数字中不同。这里有什么问题?我是否错误地检查字符串相等?

+0

这不是解决方案但是, 您不能像在tree_add的开始中那样将值指定给NULL指针如果树指针为NULL,也不会返回函数的任何指针,即使您指定tree_add函数应该返回一些东西? – Henrik 2010-02-11 16:18:25

+0

另外,你在哪里malloc左右分支?我无法在任何地方看到...... – Henrik 2010-02-11 16:22:20

+2

如果您有完全不同的问题,那么您应该从第一个问题中分离出来。否则,你不愿意接受解决你的问题的答案。无论如何,不​​要比较指向字符串的指针,比较内容 - 使用strcmp()== 0作为测试。 – 2010-02-11 17:31:32

回答

3

这部分应该如何工作?

 
    if (tree == NULL) { 
     tree->value = value; 
     tree->count = 0; 
    } 

我问,因为它会做什么总是尝试解除引用NULL如果可能的话。该代码金额为:

 
    if (tree == NULL) { 
     (NULL)->value = value; 
     (NULL)->count = 0; 
    } 

所以这是怎么回事,当它试图达到的结构的value元素接收AV。

我认为你缺少的是你需要在你的树中调用malloc()每个节点。你在开始时不能一次调用它,只能为一个节点分配足够的内存。

你大概意思是这样的:

 
    if (tree->left == NULL) { 
     tree->left = malloc(sizeof struct tree); 
     tree = tree->left; 
    } 
    /* ... */ 

然后你tree_free()函数必须递归遍历深度优先顺序的树,号召最leafward元素free()第一,最终释放第一在根整理阻止你分配。

1

strcmp需要两个字符串,并且不能处理null。请注意,char *c="\0"char *c = 0不一样。第一个是一个指向具有单个null元素的char数组的指针,第二个是空指针。

2
if (tree == NULL) { 
    tree->value = value; 
    tree->count = 0; 
} 

有一个问题就在这里,如果树是NULL,你不能使用它,你必须另外分配它首先

,则应该存储做两次的STRCMP的返回值

1

你有tree_add不适当的检查,在这里:

if (tree == NULL) { 
    tree->value = value; 
    tree->count = 0; 
} 

因为树是在原有的呼叫没有空,你会ñ写到树 - >值,它将保持NULL。当你调用strcmp时,你会在尝试读取tree-> value时遇到访问冲突。

你从来没有真正分配过tree-> left和tree-> right - 你需要在使用malloc之前分配它们。

2

一些问题:

tree = malloc(sizeof tree); 

我想你的意思sizeof *tree在这里,你在你的代码的指针 只分配空间,而不是整个结构。

if (tree == NULL) { 
    tree->value = value; 
    tree->count = 0; 
} 

如果树为NULL,则tree->value也不行。

+0

Heaths的答案更完整。 – 2010-02-11 16:24:02

0

除了其他评论,'tree_add'需要返回树和'tree_add'调用需要保存该结果。 (尽管递归调用不应该将它们保存为树,而是作为左/右指针)。