我正在慢慢学习如何在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;
}
答案 0 :(得分:1)
Why can't function access generic parameter ?
这个问题的简单回答是函数可以访问,但void *
上的进一步操作是不可能的。
使用指针算法(需要单个元素的大小)来访问元素,因为指向您传递的地址的void *
指针却不知道该数组或内存位置中每个字段的大小。因此,访问或取消引用会引导您Undefined Behaviour
。
如果要在函数内部访问该类型的每个元素,请将单个元素的size
传递给该函数,并在此基础上创建指向该类型的指针,然后使用该类型的新指针进行访问
更多阅读this
答案 1 :(得分:0)
由于@WhozCraigs关于索引超出范围的帖子,我尝试了一种方法。所以我做了一些小mods,现在程序按照它的意图行事。
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;
}