当我尝试在C lang上通用排序库中使用compelx结构时,我的代码中出现了一个问题:(你可以找到完整的代码https://github.com/Tramontz/ASD_2023)
我有一个二进制合并插入排序,它可以输入一个空指针(数组的第一个元素),并且可以处理int和string的数组(所有统一测试通过)。
现在我尝试使用它与数组:
struct record{
int id;
char* string_field_1;
int integer_field_2;
double float_field_3;
};
存储在另一个结构中
struct _StructArray{
void**array;
unsigned long el_num;
unsigned long array_capacity;
};
我必须命令记录的void**数组。
这是从csv文件中获取的数据的示例
<POSIZION:0,ID:0,String:诺托,字符串:233460,Float:32209.073312 >
<POSIZION:1,ID:1,String:piangea,字符串:4741192,Float:81176.622633 >
<POSITIZION:2,ID:2,String:spenti!,电话:1014671,浮点数:4476.013614 >
<POSIZION:3,ID:3,String:misericordia,String:496325,Float:61628.929334 >
排序模式由
switch (field) {
case 1://struct_array_get(array,0) return the first element of the array
merge_binary_insertion_sort(struct_array_get(array,0), struct_array_size(array), sizeof(struct record), k, precedes_record_string_field);
所以基本上我用一个循环把所有数据存储在structArray中的record * 数组中。
数组被正确加载,因为打印函数
for(unsigned long i=0;i<el_num;i++){
array_element = (struct record *)struct_array_get(array, i);
printf("<POSIZION:%d, ID:%d, String:%s, Integer:%d, Float:%lf >\n",i,array_element->id,array_element->string_field_1,array_element->integer_field_2,array_element->float_field_3);
}
可以显示数组中的所有记录。
所以当调用sorting函数时出现问题:
void bin_insertion_sort(void *arr, int n, size_t elementSize, CompareFunction compare) {
int i, loc, j;
void *selected = malloc(elementSize);
if (selected == NULL) {
fprintf(stderr, "Errore nell'allocazione di memoria per 'selected'\n");
exit(EXIT_FAILURE);
}
for (i = 1; i < n; ++i) {
j = i - 1;
memcpy(selected, arr + i * elementSize, elementSize);
// Find location where selected should be inserted
loc = binary_search(arr, selected, 0, j, compare, elementSize);
我存储在void * 中,选中了我想在数组中查找位置的项,并调用二分查找
int binary_search(void *arr, void *item, int low, int high, CompareFunction compare, size_t elementSize) {
if (high <= low){
return (compare(item, arr + low * elementSize) > 0) ? (low + 1) : low ;
我们只能集中在binary_search中,问题是:当我调用**return(compare(item,select + low * elementSize)> 0)时,(低+ 1):low ;**用于记录的数组,使用此比较函数
static int precedes_record_string_field(const void* r1_p, const void* r2_p) {
if (r1_p == NULL || r2_p == NULL) {
fprintf(stderr, "precedes_record_string_field: one of the parameters is a null pointer\n");
exit(EXIT_FAILURE);
}
const struct record* rec1_p = (const struct record*)r1_p;
const struct record* rec2_p = (const struct record*)r2_p;
printf("Record 1: ID=%d, String=%s, Integer=%d, Float=%f\n", rec1_p->id, rec1_p->string_field_1, rec1_p->integer_field_2, rec1_p->float_field_3);
sleep(1);
printf("Record 2: ID=%d, String=%s, Integer=%d, Float=%f\n", rec2_p->id, rec2_p->string_field_1, rec2_p->integer_field_2, rec2_p->float_field_3);
sleep(5);
return strcmp(rec1_p->string_field_1, rec2_p->string_field_1);
}
它打印rec 2数据,但不打印rec 1数据,所以我假设它可以转换void + low * elementSize指针,但不能转换我通过compare(item,void + low * elementSize)传递并存储在rec 1(item)和rec 2(void + low * elementSize)中的void* item指针。
我在内存地址管理中做错了什么?也许我用item来寻址所有的structArray,而不是record* 数组的第二个元素?
我卡住了,因为我所有的单一,空,和多字符串和整数数组的统一测试工作正常。
谢谢你们
1条答案
按热度按时间yjghlzjz1#
你的写作方式看起来非常非常复杂。
编辑:增加了第二部分,第二部分,下面。我添加了代码来使用下面相同的方法对
void**
数组进行排序,然后像原来的问题中那样对StructArray
进行排序,作为一种分离容器,方法和算法的方法的示例。这是一个大量使用复制和粘贴:这些变化只在比较函数(每行2行)和一个函数添加到StructArray
(4行),以提取指针数组的基址。把东西分开
在这里,我们有您的数据记录,4个必需的功能和一个功能,以显示结果
使用封装并围绕数据编写代码。
看这个:
这是测试你所有功能的数据。
'
main
用于测试#这里:
输出
看起来还不错。
这样更容易:首先测试所有功能。
既然你说代码已经可以处理整数,那么只要确保排序代码确实抽象了数据记录。一般来说,这只是编写正确的交换函数的情况。特别注意导航过程...
C
完整代码第二部分
第二个例子是
main.c
:test_with_struct_array()
是原始程序。第二个函数将相同的数组排序到void**
数组中,以便单独测试机制,第三个函数使用作者的原始StructArray
-稍作修改,请参见下面的代码。使用
void**
这是使用原始数据构建数组的代码:
比较函数都是不同的,因为有一个新的间接级别来访问实际数据。新函数是
cmp_[1234]
中的cmp_[5678]
,这里有一对,比较了Target
中的i_field
:不同之处在于获取数据地址。由于
StructArray
也是一个void**
的东西,这些函数也在那里使用。添加了姐妹函数来显示来自不同来源的数据,因此输出与预期完全相同。
第一个函数显示单个数据记录,因此可以被所有3种格式使用。它作为一个参数传递,因此如果需要,可以很容易地为每个测试使用备用显示。
StructArray
的变化添加此函数是为了从
StructArray
内部获取基址关于使用
StructArray
作为容器这就是在测试函数开始时如何抽象容器进行排序的。这应该适用于
void*
连续数组上的任何排序算法。希望它能帮助
第二个示例的代码
第三次测试的输出
不感兴趣,因为它是相同的数据3次,但由从相同的原始数据构建的容器生成。