【问题标题】:C89: Access violation reading 0x00 (difficulty with malloc)C89:访问冲突读取 0x00(malloc 困难)
【发布时间】:2010-02-11 16:09:52
【问题描述】:

我正在 Visual Studio 2010 Ultimate Beta (Win 7) 上开发 C89。我认为我没有正确使用malloc()。我是C新手,所以请原谅初学者的问题。

我的程序的目标是使用树计算 **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;
}

我得到的错误是:

0xC0000005:读取访问冲突 位置 0x00000000。

我在网上查了一下,这个错误似乎是由于试图访问分配不正确的内存造成的。那我做错了什么?

更新代码以反映 cmets。现在我有一个新问题。当value == "x"tree-&gt;value == "x" 时,此条件无法正常工作

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

在调试器中,我看到tree-&gt;value0x00553373 "x" char *,而value0x00553375 "x" char *。最后一位的十六进制值不同。这里有什么问题?我是否错误地检查了字符串相等性?

【问题讨论】:

  • 这不是解决方案但是,如果树指针为 NULL,您不能像在 tree_add 开始时那样为 NULL 指针赋值,而且您也不会从即使您指定了 tree_add 函数应该返回一些东西,也可以使用函数?
  • 另外,你在哪里 malloc 左右分支?我在任何地方都看不到...
  • 如果你有一个完全不同的问题,你应该从第一个开始不连贯地发布它。否则,您将不愿意接受解决您问题的答案。无论如何,不​​要比较指向字符串的指针,比较内容 - 使用 strcmp() == 0 作为测试。
  • visual studio 和 Ultimate 是矛盾的
  • @Heath 好的,我以后会这样做。过去,我针对一些我认为与原始问题不同的问题提出了一个新问题,但它的投票结果被认为是欺骗性的。

标签: c malloc null-pointer


【解决方案1】:

这部分应该如何工作?

如果(树 == NULL){ 树->值=值; 树->计数= 0; }

我问是因为它会尽可能尝试取消引用 NULL。代码相当于:

如果(树 == NULL){ (NULL)->值 = 值; (NULL)->count = 0; }

所以当它试图到达结构的value 元素时,它将接收到 AV。

我认为您缺少的是您需要为树中的 each 节点调用malloc()。您不能像在此处所做的那样在开始时调用它一次,它只会为一个节点分配足够的内存。

你的意思可能是这样的:

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

然后您的tree_free() 函数必须以深度优先顺序递归遍历树,首先在最向叶的元素上调用free(),通过最终释放您分配的第一个块在根处完成。

【讨论】:

    【解决方案2】:

    一些问题:

    tree = malloc(sizeof tree);
    

    我认为你的意思是sizeof *tree,你只是为指针分配空间 在您的代码中,而不是整个结构。

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

    如果树为 NULL,则 tree-&gt;value 不正确。

    【讨论】:

    • 希思的回答比较完整。
    【解决方案3】:
    if (tree == NULL) {
        tree->value = value;
        tree->count = 0;
    }
    

    这里有个问题,如果tree是NULL就不能使用,必须先分配

    另外,你应该存储 strcmp 的返回值,而不是重复两次

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您在 tree_add 中的检查不正确,此处:

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

        由于在原始调用中 tree 不是 NULL,因此您不会写入 tree->value 并且它将保持 NULL。然后,当您调用 strcmp 时,您会在尝试从 tree->value 读取时遇到访问冲突。

        你从来没有真正分配树->左和树->右-你需要在使用之前用 malloc 分配它们。

        【讨论】:

          【解决方案6】:

          除了其他 cmets,“tree_add”需要返回树,“tree_add”调用需要保存该结果。 (虽然递归调用不应该将它们保存为树,而是作为左/右指针)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-17
            • 2019-05-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多