gpt4 book ai didi

c - 如何在 C 中编写接受比较器的函数?

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:45 24 4
gpt4 key购买 nike

我有一个结构 vector 将它的数据保存在一个双空指针中。该结构如下所示:

typedef struct vector {
void **data;
int capacity;
int size;
} vector;

我试图在某种程度上复制 C++ 中的 std::find 函数,以在我拥有的 vector 中查找项目。我通过创建一个函数 vector_find 来做到这一点:

int vector_find(vector* v, void *elem, __compar_fn_t cmp)
{
for (int i = 0; i < v->size - 1; i++)
{
if(cmp(v->data[i], elem) == 0)
{
return i;
}
}
return -1;
}

这个函数可以在我的 vector.c 文件中找到。它接受比较器功能。如果它找到该元素,它将返回它在 vector 中的位置。

这都在我的 vector.c 文件中定义。

现在我试图在我的一个程序中使用这个函数,在这个函数中:

int cstring_cmp(const void *a, const void *b)
{
const char *ia = *(const char **)a;
const char *ib = *(const char **)b;
printf("%s %s", ia, ib);
return strcmp(ia, ib);
}

void
execute(vector* tokens)
{
if (vector_find(tokens, ";", cstring_cmp) > -1)
{
printf("semicolon found");
}
}

但是,当我运行这个函数时,我得到了一个带有以下错误的段错误:

Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
120 ../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory.

我已经验证了一些事情:

  1. 我已确认错误发生在我的execute 函数中。特别是当我调用 vector_find 时。

  2. 我已验证出现此错误是否 tokens 为空。这很有趣,因为如果我传递给 vector_find 的 vector 为空,则 vector_find 中的 for 循环永远不会执行。

  3. 我已将其包含在 vector.c 和我正在运行的文件中。

我也试过这种格式:

int vector_find(vector* v, void *elem, int (*cmp) (const void*, const void*))
{
for (int i = 0; i < v->size; i++)
{
if((*cmp) (v->data[i], elem) == 0)
{
return i;
}
}
return -1;
}

...并得到同样的错误。

我这样做对吗?显然不是——我的错误在哪里?

最佳答案

您的比较函数期望它的每个参数都是一个 char **。但是,您调用 vector_find 时将 char * 作为第二个参数传递给 cmp。尝试将 char * 用作 char ** 会调用未定义的行为,因为您最终传递给 strcmp 实际上是 char.

您没有说明如何填充vector,但我猜data 的元素是char * 类型。在这种情况下,比较函数应该期待 char * 而不是 char **

int cstring_cmp(const void *a, const void *b)
{
const char *ia = a;
const char *ib = b;
printf("%s %s", ia, ib);
return strcmp(ia, ib);
}

关于c - 如何在 C 中编写接受比较器的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54739944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com