C89:访问冲突读取 0x00(malloc 困难)

发布于 2024-08-21 08:10:56 字数 1879 浏览 8 评论 0原文

我正在 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。

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

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

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

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

I am developing C89 on Visual Studio 2010 Ultimate Beta (Win 7). I don't think I'm using malloc() correctly. I am new to C, so please excuse the beginner question.

The goal of my program is to count the occurrence of words in **argv using a tree.

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;
}

The error I get is:

0xC0000005: Access violation reading
location 0x00000000.

I looked online, and it appears that this error is caused by trying to access improperly allocated memory. So what am I doing wrong?

UPDATED code to reflect comments. Now I have a new problem. This condition is not working properly when value == "x" and tree->value == "x"

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

In the debugger, I see that tree->value is 0x00553373 "x" char *, whereas value is 0x00553375 "x" char *. The hex value is different in the last digit. What is wrong here? Am I checking for string equality incorrectly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

何止钟意 2024-08-28 08:10:56

这部分应该如何工作?

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

我问这个问题是因为它所做的总是尝试在可能的情况下取消引用 NULL。代码相当于:

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

因此,当 AV 尝试到达结构体的 value 元素时,它将接收 AV。

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

您的意思可能是这样的:

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

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

How is this part supposed to work?

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

I ask because what it will do is always attempt to dereference NULL if possible. The code amounts to:

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

So that is going to receive the AV when it attempts to reach the value element of the struct.

I think what you are missing is that you need to call malloc() for each node in your tree. You can't call it once at the beginning as you have done here, that only allocates enough memory for one node.

You probably meant something like:

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

Then your tree_free() function must recursively traverse the tree in depth-first order, calling free() on the most leafward elements first, finishing at the root by ultimately freeing the first block you allocated.

烏雲後面有陽光 2024-08-28 08:10:56

一些问题:

tree = malloc(sizeof tree);

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

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

如果tree为NULL,那么tree->value是不行的。

Some problems :

tree = malloc(sizeof tree);

I think you mean sizeof *tree here, you're only allocating space for a pointer
in your code, not for the entire struct.

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

If tree is NULL then tree->value is not ok.

美人如玉 2024-08-28 08:10:56
if (tree == NULL) {
    tree->value = value;
    tree->count = 0;
}

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

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

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

there is a problem here, if tree is NULL you can't use it, you must allocate it first

Additionally, you should store the return value of strcmp instead of doing it twice

梦里°也失望 2024-08-28 08:10:56

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

strcmp expects two strings and cannot handle null. Note that char *c="\0" is not the same as char *c = 0. The first is a pointer to a char array with a single null element, the second is a null pointer.

要走干脆点 2024-08-28 08:10:56

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

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

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

您实际上从未分配过tree->left 和tree->right - 您需要在使用之前使用malloc 分配它们。

You have an improper check in tree_add, here:

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

Since tree is not-NULL in the original call, you will not write to tree->value and it will stay NULL. When you then call strcmp, you get the access violation while trying to read from tree->value.

You never actually allocate tree->left and tree->right - you need to allocate these with malloc before using.

子栖 2024-08-28 08:10:56

除了其他注释之外,“tree_add”需要返回树,并且“tree_add”调用需要保存该结果。 (尽管递归调用不应该将它们保存为树,而是保存为左/右指针)。

In addition to the other comments, 'tree_add' needs to return tree and the 'tree_add' calls needs to save that result. (Although the recursive calls shouldn't save them as tree, but as the left/right pointers).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文