【问题标题】:Why can't function access generic parameter为什么函数不能访问泛型参数
【发布时间】:2012-11-17 03:08:15
【问题描述】:

我正在慢慢学习如何用 C 语言编写泛型函数,现在经常遇到麻烦。我正在制作一个合并两个数组的程序,在这个实现中是两个 int 数组。第一个问题也导致了第二个问题,compareints(函数)不访问传递的参数之一(void *):我不知道为什么?我已经盯着屏幕很久了...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//makes union of two generic arrays and eliminates duplicates if there are some...
void **
unite(int (*comp)(void *f, void *s), void **first, void **second, int f_size, int s_size,     int bytes, int *x)
{
     int i;
     void **arr=malloc(bytes*(f_size+s_size));
     for(i=0; i<f_size+s_size; i++)
     {
         /* first bigger */
         if(((*comp)(*first, *second))>0)
         {
            *(arr+i)=*(first++);
         }
         /* second bigger */
         else if(((*comp)(*first, *second))<0)
         {
            *(arr+i)=*((second++));
         }
         /* equal => just one copy */
         else
         {
            *(arr+i)=*(first++);
            second++;
         }
     }
     *x=i;
     return arr;
 }

 int
 compareints(void *first, void *second)
 {
     if(*((int *)first)>*((int *)second)) //can't access the memoryloc in second...
         return 1;
     else if(*((int *)first)<*((int *)second))
         return -1;
     else
         return 0;
 }

 int main(int argc, const char * argv[])
 {

     int arr[10]={1, 2, 4, 12, 22, 29, 33, 77, 98};
     int arr2[5]={3, 5, 7, 8, 9};
     void **first=malloc(sizeof(int *)*10);
     void **second=malloc(sizeof(int *)*5);
     //make pointers to static arrays in dynamic arrays
     int f_ind, s_ind;
     for(f_ind=0; f_ind<10; f_ind++)
         first[f_ind]=&arr[f_ind];
     for(s_ind=0; s_ind<5; s_ind++)
         second[s_ind]=&arr2[s_ind];
     int i;
     //make union of the two arrays and print out the result
     void **ret=unite(&compareints, first, second, 10, 5, sizeof(int), &i);
     for(int k=0; k<i; k++)
         printf("%d  ", *((int *)ret[k]));
     return 0;
 }

【问题讨论】:

  • 你之前不是问过同样的问题吗? how to initialize generic functions in c
  • @Nocturno 好吧,我看到我的问题之间有相似之处,但它们是不同的。
  • 顺便说一句,当 for 循环到达 5 时,您的代码在 unite() 中崩溃,原因应该很明显。
  • @WhozCraig 感谢您指出这一点,我自己没有看到这一点。我还发现了一些令人尴尬的事情,该函数试图颠倒顺序.. yikees

标签: c generics


【解决方案1】:

感谢@WhozCraigs 关于索引超出范围的帖子,我尝试了一种方法。所以我做了一些小模组,现在程序可以按预期进行。

void **
unite(int (*comp)(void *f, void *s), void **first, void **second, int f_size, int s_size, int bytes, int *x)
{
    int i;
    int f_ind=0, s_ind=0;
    void **arr=malloc(bytes*(f_size+s_size));
    for(i=0; i<f_size+s_size; i++)
    {
        /* first bigger */
        if(((*comp)(*first, *second))>0)
        {
            s_ind++;
            if(s_ind<s_size)
                *(arr+i)=*(second++);
            else
            {
                f_ind++;
                if(f_ind<f_size)
                    *(arr+i)=*(first++);
                else
                    break;
            }
        }
         /* second bigger */
        else if(((*comp)(*first, *second))<0)
        {
            f_ind++;
            if(f_ind<f_size)
                *(arr+i)=*(first++);
            else
            {
                s_ind++;
                if(s_ind<s_size)
                    *(arr+i)=*(second++);
                else
                    break;
            }
        }
        /* equal => just one copy */
        else
        {
            f_ind++;
            s_ind++;
            if(f_ind<f_size && s_ind==s_size)
            {
                *(arr+i)=*(first++);
            }
            else if(f_ind==f_size && s_ind<s_size)
            {
                *(arr+i)=*(second++);
            }
            else
            {
                *(arr+i)=*(first++);
                second++;
            }  
        }
    }
    *x=i;
    return arr;
}

【讨论】:

    【解决方案2】:
    Why can't function access generic parameter ?
    

    这个问题的简单答案是函数可以访问,但无法对void * 进行进一步操作。

    使用指针算法(需要单个元素的大小)访问元素,因为指针 void * 指向您传递的地址,但不知道该数组或内存位置中每个字段的大小。因此访问或取消引用将引导您到Undefined Behaviour

    如果你想在函数中访问该类型的每个元素,请将单个元素的size 传递给该函数,并在此基础上创建指向同一类型的指针,然后使用该类型的新指针进行访问。

    更多阅读this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      相关资源
      最近更新 更多