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

时间:2019-02-18 03:06:00

标签: c

我有一个结构vector,将其数据保存在double void指针中。结构看起来像这样:

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

...并遇到相同的错误。

我这样做正确吗?显然不是-我的错误在哪里?

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

如果我没看错,您编写的比较器假装vectorconst char*。不是。随后的C字符串比较可能不会碰到可能为null的终止符,并且将超出范围。

相反,编写一个比较器,该比较器实际上将vector个对象与要与之比较的对象进行比较。