我在 C 中使用一棵树来跟踪未定义和不同数量的输入字段。我有一个包含一组字段的结构,如下所示:
struct mystruct {
int id, mpid;
char *name;
struct myotherstruct *myostr;
};
我有一个这种类型的指针实例( mystruct ),我为其分配内存,然后用从文件中读取的输入填充这些结构值。然后,我使用 search.h 中的 tsearch 函数将 mystruct 对象添加到 mystruct 树。我遇到的问题是,如果我使用 tfind 函数从树中检索 mystruct 指针,则返回的 mystruct 内存不记得我在创建值之前分配并指向的 myotherstruct 指针数据添加到那个树。
一般顺序如下:
struct mystruct {
int id, mpid;
char *name;
struct myotherstruct *myostr;
};
struct myotherstruct {
int spid;
};
// allocate memory to temporary mystruct pointer
// add mpid field to mystruct pointer ( used in comparison function )
if( // tfind == NULL )
{
// set id value
// allocate char memory and strncpy correct value in
// allocate myotherstruct memory and assign all values
// tsearch for this newly created mystruct memory chunk so that it is added to tree
}
else
{
// fails here when attempting to access the data returned by mytfind
}
...
使用 gdb,程序第一次非常清楚地进入 if 循环(因为树是空的)并创建一个有效且完整的 mystruct 指针,并分配适当的内存。当 tsearch 返回它的输出时,内存位置与我填写的 mystruct 指针的位置不同,然后我无法为 mystruct->myotherstruct 变量(例如 spid)进行打印。尝试在 gdb 中打印时得到的确切输出是:无法访问地址 0x----- 处的内存,其中 - 是我显然无法访问的内存中的各个位置。
我怀疑我的比较函数可能存在问题,因为我只是比较 mystruct mpid 字段以确定是否存在 mystruct 对象的树节点,但是我对 C 和 tsearch/tfind 功能的缺乏经验在这里显示了一点。希望有更多经验的人能够帮助我,因为各种 tsearch.h 网页上提供的示例不能处理非常复杂的示例。在此先感谢您的帮助!
PS:代码必须保留在 C 中,所以语言交换是不够的 :(
编辑:
这是我的比较功能:
int distcmp(const void *a, const void *b){
return ((int)((struct mystruct *)a)->mpid) != (int)(((struct mystruct *)b)->mpid);
}
另外,我最初使用 tfind 是因为我想知道树中是否存在特定值。如果它不存在(它返回 NULL )然后它进入 if 循环并填充新的 mystruct 对象并将其添加到树中(使用 tsearch )。如果它已经存在,则指向该对象的指针来自 tfind,我将其分配给 mystruct 指针并在代码的 else 部分中使用。希望这会有所帮助。再次感谢。
解决了:
只是为了更新,问题是从 tsearch 和 tfind 返回的指针不是 mystruct 类型。它是指向与我的搜索匹配的 mystruct 值的内存位置的指针。在这种情况下,可以通过使用 * 访问返回的指针并将该值传递给 mystruct 指针来解决问题。感谢那些评论的人。