所以..我有这样的事情。它应该创建具有10,20,50 100个最多5000个随机数的数组,然后使用Insertion Sort进行排序并打印出完成了多少次比较和交换。但是,当我达到200时,我得到一个运行时异常数字大数组..“访问冲突写入位置0x00B60000。” ..有时我甚至没有达到200并在10个数字后立即停止。我完全不知道。
long *arrayIn;
int *swap_count = (int*)malloc(sizeof(int)), *compare_count = (int*)malloc(sizeof(int));
compare_count = 0;
swap_count = 0;
int i, j;
for (j = 10; j <= 1000; j*=10) {
for (i = 1; i <= 5; i++){
if (i == 1 || i == 2 || i == 5) {
int n = i * j;
arrayIn = malloc(sizeof(long)*n);
fill_array(&arrayIn, n);
InsertionSort(&arrayIn, n, &swap_count, &compare_count);
print_array(&arrayIn, n, &swap_count, &compare_count);
compare_count = 0;
swap_count = 0;
free(arrayIn);
}
}
}
编辑:好的,这个免费的(arrayIn);我得到这个“堆栈cookie检测代码检测到基于堆栈的缓冲区溢出。”我无处可去但是没有它,它只是“访问违规写入位置0x00780000”。但我最终得到200个数字
void fill_array(int *arr, int n) {
int i;
for (i = 0; i < n; i++) {
arr[i] = (RAND_MAX + 1)*rand() + rand();
}
}
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count) {
int i, j, t;
for (j = 0; j < n; j++) {
(*compare_count)++;
t = arr[j];
i = j - 1;
*swap_count = *swap_count + 2;
while (i >= 0 && arr[i]>t) { //tady chybí compare_count inkrementace
*compare_count = *compare_count + 2;
arr[i + 1] = arr[i];
(*swap_count)++;
i--;
(*swap_count)++;
}
arr[i + 1] = t;
(*swap_count)++;
}
}
答案 0 :(得分:2)
我确信你的编译器告诉你出了什么问题。
您正在将long**
传递给期望该行int*
的函数
fill_array(&arrayIn, n);
函数原型是
void fill_array(int *arr, int n)
与其他功能相同的问题。从那里,任何事情都可能发生。
总是,始终注意编译器给你的警告。
MAJOR EDIT
首先 - 是的,数组的名称已经是指针。
第二 - 在代码开头声明一个函数原型;然后编译器会抛出有用的消息,这将有助于你抓住这些
第三 - 如果要将简单变量的地址传递给函数,则不需要malloc
;只需使用变量的地址。
第四 - rand()
函数返回0到RAND_MAX
之间的整数。代码
a[i] = (RAND_MAX + 1) * rand() + rand();
是一种迂回的获取方式
a[i] = rand();
因为(RAND_MAX + 1)
会溢出并给你零...如果你真的想要得到一个“非常大”的随机数,你将不得不做以下事情:
1)确保a
是long *
(使用正确的原型等)
2)在添加/乘法之前转换数字:
a[i] = (RAND_MAX + 1L) * rand() + rand();
可能会这样做 - 或者你可能需要再向(long)
施展一次;我永远不会记得我的优先顺序所以我通常会这样做
a[i] = ((long)(RAND_MAX) + 1L) * (long)rand() + (long)rand();
100%肯定。
将这些课程和其他课程放在一起,这是编辑和运行的代码的编辑版本(我必须“发明”print_array
) - 我已经编写了注释,需要将代码更改为工作。上面的最后一点(制作长随机数)在此代码中尚未考虑。
#include <stdio.h>
#include <stdlib.h>
// include prototypes - it helps the compiler flag errors:
void fill_array(int *arr, int n);
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count);
void print_array(int *arr, int n, int *swap_count, int *compare_count);
int main(void) {
// change data type to match function
int *arrayIn;
// instead of mallocing, use a fixed location:
int swap_count, compare_count;
// often a good idea to give your pointers a _p name:
int *swap_count_p = &swap_count;
int *compare_count_p = &compare_count;
// the pointer must not be set to zero: it's the CONTENTs that you set to zero
*compare_count_p = 0;
*swap_count_p = 0;
int i, j;
for (j = 10; j <= 1000; j*=10) {
for (i = 1; i <= 5; i++){
if (i == 1 || i == 2 || i == 5) {
int n = i * j;
arrayIn = malloc(sizeof(long)*n);
fill_array(arrayIn, n);
InsertionSort(arrayIn, n, swap_count_p, compare_count_p);
print_array(arrayIn, n, swap_count_p, compare_count_p);
swap_count = 0;
compare_count = 0;
free(arrayIn);
}
}
}
return 0;
}
void fill_array(int *arr, int n) {
int i;
for (i = 0; i < n; i++) {
// arr[i] = (RAND_MAX + 1)*rand() + rand(); // causes integer overflow
arr[i] = rand();
}
}
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count) {
int i, j, t;
for (j = 0; j < n; j++) {
(*compare_count)++;
t = arr[j];
i = j - 1;
*swap_count = *swap_count + 2;
while (i >= 0 && arr[i]>t) { //tady chybí compare_count inkrementace
*compare_count = *compare_count + 2;
arr[i + 1] = arr[i];
(*swap_count)++;
i--;
(*swap_count)++;
}
arr[i + 1] = t;
(*swap_count)++;
}
}
void print_array(int *a, int n, int* sw, int *cc) {
int ii;
for(ii = 0; ii < n; ii++) {
if(ii%20 == 0) printf("\n");
printf("%d ", a[ii]);
}
printf("\n\nThis took %d swaps and %d comparisons\n\n", *sw, *cc);
}
答案 1 :(得分:1)
您正在为某些指针指定文字值0
。您还将“指针”与“指针地址”混合在一起; &swap_count
给出指针的地址,而不是其值的地址。
首先,这里不需要malloc:
int *swap_count = (int*)malloc(sizeof(int)) ..
只需要一个整数:
int swap_coint;
然后你不需要做
swap_coint = 0;
到这个指针(导致你的错误)。当然,对常规int
变量这样做很好。
(如果上面已修复,&swap_count
应该有效,所以也不要改变它。)
答案 2 :(得分:0)
正如我在评论中所说,你传递指针的地址,指向实际值。
使用&符号前缀(&amp;),您将传递某些内容的地址。 您只能在传递基本类型时使用它。
E.g。通过传递int来填充数组。但是你传递指针,所以不需要使用&符号。
实际发生的是您正在查看指针的地址空间,而不是指针最终指向的实际值。这会导致各种内存冲突。
删除所有&amp;你在哪里输入指针这些行:
fill_array(&arrayIn, n);
InsertionSort(&arrayIn, n, &swap_count, &compare_count);
print_array(&arrayIn, n, &swap_count, &compare_count);
所以它变成了:
fill_array(arrayIn, n);
InsertionSort(arrayIn, n, swap_count, compare_count);
print_array(arrayIn, n, swap_count, compare_count);
我还注意到你为原始类型分配内存,这可以更简单地完成:
int compare_count = 0;
int swap_count = 0;
但如果您选择使用最后一段代码,请使用&amp; swap_count和&amp; compare_count,因为您传递的是基本类型,而不是指针!