【发布时间】:2019-05-21 09:33:58
【问题描述】:
我创建了一个名为 ArrayCount 的结构,其中包含一个双精度数组和一个整数,该整数应该计算数组出现的频率。
如果双数组的大小为n,想法是,创建一个大小为n的struct ArrayCount的数组! (n! 在我的代码中称为 m)。
这个想法是保护 ArrayCount 数组中的每个排列,计算每个排列的出现次数,对于给定的算法。但这只是背景信息,不是问题的一部分。
我在释放为双数组分配的内存时遇到问题。 奇怪的是,大约 1/10 次我的代码编译时没有错误消息,有时会出现不同的错误消息。
-
错误信息:
munmap_chunk(): invalid pointer Aborted (core dumped) -
错误信息:
free(): invalid size Aborted (core dumped) -
错误信息:
Segmentation fault (core dumped)
部分代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double* array_copy(const double* a, int n) {
srand(time(NULL));
double* copy = calloc(n, 8);
for(int i = 0; i < n; i++) {
copy[i] = a[i];
}
return copy;
}
void shuffle(double* a, int n) {
for(int i = n - 1; i >= 0; i--) {
time_t t;
/* Intializes random number generator */
srand((unsigned) time(&t));
double* copy = array_copy(a, i + 1);
//Generates random numbers in the closed intervall [0,i].
int random = rand() % (i + 1);
a[i] = a[random];
a[random] = copy[i];
free(copy);
}
}
// Refers to a double array and counts how often this array has
occurred yet.
typedef struct {
double* array;
int counter;
} ArrayCount;
// Computes the factorial of n: n!.
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
/*
Saves all permutations in array_counts, for a given double array of
the length n and counts how often each permutations occurs.
(Hint given by our supervisor: Save a copy of a in array_counts)
*/
void update_array_counts(/*INOUT*/ ArrayCount* array_counts, int m,
/*IN*/ const double* a, int n) {
double* copy_a = array_copy(a, n);
//Increases the counter by 1, if a is already listed in
array_counts
for(int i = 1; i <= m; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(array_counts[i].array[j] == a[j]) count++;
}
if(count == n) {
array_counts[i].counter++;
free(copy_a);
return;
}
}
//Saves a in array_counts and sets the counter to 1, if a is not
listed in array_counts, yet
for(int i = 1; i <= m; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(array_counts[i].array[j] == 0) count++;
}
if(count == n) {
for(int j = 0; j < n; j++) {
array_counts[i].array[j] = a[j];
}
array_counts[i].counter = 1;
free(copy_a);
return;
}
}
}
// Gibt die Häufigkeit der verschiedenen Permutationen eines Arrays
der Länge n aus.
void shuffle_frequency(int n) {
double a[n];
for (int i = 0; i < n; i++) {
a[i] = i;
}
int m = factorial(n);
ArrayCount* array_counts = calloc(m, sizeof(ArrayCount));
for(int i = 1; i <= m; i++){
array_counts[i].array = calloc(n, sizeof(double));
}
for (int i = 0; i < 1000 * m; i++) {
shuffle(a, n);
update_array_counts(array_counts, m, a, n);
}
for (int i = 1; i <= m; i++) {
printf("%4d%8d ", i, array_counts[i].counter);
}
//The next free-statement is causing problems.
for(int i = 1; i <= m; i++) {
printf("i = %d\n", i);
free(array_counts[i].array);
}
free(array_counts);
}
int main(void) {
shuffle_frequency(4);
return 0;
}
我做错了什么?
【问题讨论】:
-
你能创建一个以同样方式崩溃的更最小示例吗?
-
数组索引从
0开始。如果为array_counts分配m元素计数,则无法使用i=m访问array_counts[i]。 -
与您的问题描述无关:您对
srand()的使用是错误的。放入main();不要在循环中调用srand()。 -
calloc(n, 8);幻数8看起来很可疑。 -
array_copy()没用;如果您要交换两个索引的值,只需将一个保存在临时double中,而不是复制整个数组。这将删除至少 1000 次对calloc()和free()的调用。
标签: c memory free allocation