C 动态数组mergesort算法中的Seg故障问题
我试图用c语言中的动态数组结构实现mergesort算法,但是当我调用函数分割原始数组而不是得到两个子数组时,我得到了一个seg错误。 我很确定这会涉及到我如何定义结构的大小,但我无法克服。以下是我如何定义结构以及如何创建和初始化结构:C 动态数组mergesort算法中的Seg故障问题,c,algorithm,pointers,mergesort,dynamic-arrays,C,Algorithm,Pointers,Mergesort,Dynamic Arrays,我试图用c语言中的动态数组结构实现mergesort算法,但是当我调用函数分割原始数组而不是得到两个子数组时,我得到了一个seg错误。 我很确定这会涉及到我如何定义结构的大小,但我无法克服。以下是我如何定义结构以及如何创建和初始化结构: typedef struct dynarray { void **memory; size_t allocated; //total size of the array size_t used; //used size of the arra
typedef struct dynarray
{
void **memory;
size_t allocated; //total size of the array
size_t used; //used size of the array
int index;
} dynarray;
//creates a new, empty, dynarray
void create_dynarray(dynarray **array, size_t size)
{
*array = calloc(size, sizeof(array));
(*array)->memory = NULL;
(*array)->allocated = 0;
(*array)->used = 0;
(*array)->index = -1;
}
这就是我定义mergesort函数的方法
//function used to slice the dynarray in two subarrays and call merge function
void* dynarray_mergesort(dynarray *param){
if(dynarray_length(param)>1){
param->index = 0;
printf("index of first:%d\t", param->index);
size_t size = param->used;
size_t m = size/2;
size_t n = size - size/2;
struct dynarray *l;
create_dynarray(&l, m);
printf("index of left:%d\t", l->index);
struct dynarray *r;
create_dynarray(&r, n);
printf("index of right:%d\n", r->index);
for(int i = 0 ; i < m; i++){
add_elem(l, param->memory[i]);
}for(int j = m; j < n; j++){
add_elem(r, param->memory[j]);
}
puts("first");
print_array(l);
puts("second");
print_array(r);
dynarray_mergesort(l);
dynarray_mergesort(r);
//dynarray_merge(param, l , r, size);
}
return param;
}
//function used to mergesort the array
void* dynarray_merge(dynarray *param, dynarray *l, dynarray *r, int size){
int i,j,k;
while(i < size/2 && j < size-size/2){
if(l->memory[i] < r->memory[j]){
param->memory[k] = l->memory[i];
i++;
k++;
}else{
param->memory[k] = r->memory[j];
j++;
k++;
}
}
while(i < size/2)
param->memory[k++] = l->memory[i++];
}while(j < size-size/2){
param->memory[k++] = r->memory[j++];
}
return param;
}
//function used to mergesort the array
void* dynarray_merge(dynarray *param, dynarray *l, dynarray *r, int size){
int i,j,k;
while(i < size/2 && j < size-size/2){
if(l->memory[i] < r->memory[j]){
param->memory[k] = l->memory[i];
i++;
k++;
}else{
param->memory[k] = r->memory[j];
j++;
k++;
}
}
while(i < size/2){
param->memory[k++] = l->memory[i++];
}while(j < size-size/2){
param->memory[k++] = r->memory[j++];
}
return param;
}
create\u dynarray
函数的内部
*array = calloc(size, sizeof(array));
应改为:
*array = calloc(size, sizeof(**array))
要执行您实际想要执行的操作(使用元素
size dynarray*
size为数组分配内存)。除了问题下方注释中提到的分配不足之外(例如,需要*array=calloc(size,sizeof**array);
),还有一个简单的错误导致您的错误(您还有其他错误)。您在dynarray\u mergesort
中的size
变量中存储字节数,而不是指针数。因此在dynarray\u mergesort
中,当您声明size\u t size=param->已使用时;
大小值是sizeof(void*)的倍数
(例如sizeof(a_指针)
)乘以实际使用的指针数。这会导致m
和n
的值不正确
要解决此问题,您只需执行以下操作:
size_t size = param->used / sizeof(void*);
您的循环限制出现另一个错误:
for(size_t j = m; j < n; j++){
add_elem(r, param->memory[j]);
}
(注意:上面的i
和j
的正确类型都是size\u t
对应于m
和n
并防止“有符号和无符号整数表达式之间的比较”)
正如我在评论中指出的,您在dynarray\u merge
中存在未初始化的值问题。您需要初始化i
和k
,例如
int i=0, j=0, k=0;
在尝试之前:
i++;
k++;
通过这些更改,您的代码可以毫无问题地运行到底(除了内存泄漏):
您在合并列表时仍有问题(留给您进一步调查),但您的SegFault问题已解决。如果您还有其他问题,请告诉我。(除了修复留给您的
merge
算法所需的更改)*array=calloc(大小、大小(数组));
应该是sizeof**array
*array=calloc(size,sizeof(array))没有分配足够的内存。考虑什么是“代码>数组<代码>……考虑是否需要<代码> int index;< /C>作为结构的一部分。你有<代码>使用< /Calp>填充的指针数。除了一个之外,<代码>索引>代码>服务> <代码>使用< /代码>什么?不能用负的INDE启动任何东西。在dynarray\u merge
中,当您第一次执行i++;
和k++;
时,i和k++;
的值是多少?关于:void create\u dynarray(dynarray**array,size\t size){*array=calloc(size,sizeof(array));
表达式:sizeof(array)
结果是指针的长度(4或8,取决于底层硬件体系结构和某些编译器选项)建议:*array=calloc(size,sizeof(dynarray));
并始终检查(!=NULL)返回值以确保操作成功。如果不成功,请调用peror()
和exit()
请像我这次为您所做的那样正确地设置您的问题的格式注意:您可能需要研究mergesort的自底向上版本,以消除由于大型数组上的深度递归而导致的堆栈耗尽。
int i=0, j=0, k=0;
i++;
k++;
$ ./bin/dynarraymergeorig
index of first:0 index of left:-1 index of right:-1
first
18 14
second
20 16 12
index of first:0 index of left:-1 index of right:-1
first
18
second
14
index of first:0 index of left:-1 index of right:-1
first
20
second
16 12
index of first:0 index of left:-1 index of right:-1
first
16
second
12
18