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 *、それはですが、valueはです0x00553375 "x" char *。16進値は最後の桁で異なります。ここで何が問題になっていますか?文字列の同等性を誤ってチェックしていますか?

4

6 に答える 6

3

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.

于 2010-02-11T16:16:59.723 に答える
2
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

于 2010-02-11T16:15:26.310 に答える
2

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.

于 2010-02-11T16:16:08.370 に答える
1

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.

于 2010-02-11T16:14:48.183 に答える
1

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.

于 2010-02-11T16:15:45.043 に答える
0

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).

于 2010-02-11T16:41:40.660 に答える