C89:访问冲突读取 0x00(malloc 困难)
我正在 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- >value
为 0x00553373 "x" char *
,而 value
为 0x00553375 "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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这部分应该如何工作?
我问这个问题是因为它所做的总是尝试在可能的情况下取消引用 NULL。代码相当于:
因此,当 AV 尝试到达结构体的
value
元素时,它将接收 AV。我认为您缺少的是您需要为树中的每个节点调用
malloc()
。您不能像此处所做的那样从一开始就调用它一次,这只会为一个节点分配足够的内存。您的意思可能是这样的:
然后您的
tree_free()
函数必须以深度优先顺序递归遍历树,首先对最靠叶的元素调用free()
,最后在通过最终释放您分配的第一个块来获取根。How is this part supposed to work?
I ask because what it will do is always attempt to dereference NULL if possible. The code amounts to:
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:
Then your
tree_free()
function must recursively traverse the tree in depth-first order, callingfree()
on the most leafward elements first, finishing at the root by ultimately freeing the first block you allocated.一些问题:
我认为你的意思是
sizeof *tree
这里,你只是为指针分配空间在您的代码中,而不是整个结构。
如果tree为NULL,那么
tree->value
是不行的。Some problems :
I think you mean
sizeof *tree
here, you're only allocating space for a pointerin your code, not for the entire struct.
If tree is NULL then
tree->value
is not ok.这里有一个问题,如果tree是NULL你就不能使用它,你必须先分配它
此外,你应该存储strcmp的返回值而不是重复两次
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
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 aschar *c = 0
. The first is a pointer to a char array with a single null element, the second is a null pointer.您在tree_add 中进行了不正确的检查,此处:
由于在原始调用中tree 不是NULL,因此您不会写入tree->value 并且它将保持为NULL。然后,当您调用 strcmp 时,您会在尝试从 tree->value 读取时遇到访问冲突。
您实际上从未分配过tree->left 和tree->right - 您需要在使用之前使用malloc 分配它们。
You have an improper check in tree_add, here:
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.
除了其他注释之外,“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).