我创建了一个名为ArrayCount的结构,其中包含一个双精度数组和一个整数,该整数应计算数组出现的频率。
如果双精度数组的大小为n,则想法是创建大小为n的struct ArrayCount的数组! (n!在我的代码中称为m)。
这个想法是为了保护给定算法的ArrayCount-array中的每个排列,计算每个排列的出现次数。但这只是背景信息,而不是问题的一部分。
在释放为双数组分配的内存时遇到问题。 奇怪的是,我的代码的编译次数是〜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 :(得分:1)
我在释放分配给内存的内存时遇到问题 双数组。奇怪的是,〜1/10倍我的代码编译没有 错误消息,有时还会显示不同的错误消息。
符合而没有错误消息或运行而没有错误消息?我看到运行时错误(准确地说是Segfault或Abort信号)没有编译时。
for (int i = 1; i <= m; i++) {
迭代m
元素数组的正确方法是
for(int i=0; i < m; i++){
如注释中所指出,偏移量从0
开始到m-1
,而不是m
。这使得free(array_counts[i].array)
变成free(array_counts[m].array)
array_counts[m]
的情况是什么?可能有各种各样的事情,它们在运行时可能是确定性的,也可能是不确定性的,但它在您分配的内存之外。在这种情况下,free
的行为是不确定的,因为只要传递了未分配给malloc
和朋友的地址,它的行为就可以了。
考虑http://man7.org/linux/man-pages/man3/malloc.3.html,这是free
的联机帮助页的副本:
free()函数释放ptr指向的内存空间 必须是先前调用malloc(),calloc()或返回的 realloc()。否则,或者如果已经调用了free(ptr) 之前,会发生未定义的行为。