如何克服 c 中的 double free or corruption (out) Aborted (core dumped)
How to overcome double free or corruption (out) Aborted (core dumped) in c
我正在尝试创建一个 zoom_image 函数,该函数使用离散傅立叶变换来缩放灰度图像。如果图像尺寸小于或等于 4*4 但如果尺寸增加,我包含的代码将起作用。它给出 'double free or corruption (out) Aborted (core dumped)' 错误
我已经尝试了我的代码的 fft_d 和 ifft_2d 功能 如果输入大小很小它可以工作 如果输入大小很大它会给出上述错误
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
struct complex{
float real;
float im;
};
typedef struct complex complex;
complex w(int i, int n) {
complex result;
result.real = cos(2*M_PI*i/n);
result.im = -sin(2*M_PI*i/n);
return result;
}
complex wp(int i, int n) {
complex result;
result.real = cos(2*M_PI*i/n);
result.im = sin(2*M_PI*i/n);
return result;
}
complex mul(complex a, complex b) {
complex result;
result.real = a.real*b.real - a.im*b.im;
result.im = a.real*b.im + b.real*a.im;
return result;
}
complex divi(complex a, complex b) {
complex result;
result.real = (a.real*b.real + a.im*b.im)/(b.real*b.real + b.im*b.im);
result.im = (-a.real*b.im + b.real*a.im)/(b.real*b.real + b.im*b.im);
return result;
}
complex add(complex a, complex b) {
complex result;
result.real = a.real+b.real ;
result.im = a.im+b.im;
return result;
}
complex sub(complex a, complex b) {
complex result;
result.real = a.real - b.real;
result.im = a.im - b.im;
return result;
}
void printComplex(complex var) {
printf("%f i%f\n",var.real,var.im);
}
void printComplexS(complex var) {
printf("%f i%f",var.real,var.im);
}
#include<stdio.h>
#include<stdlib.h>
#include"complex.h"
static int gb=0;
complex* _fft(complex *arr, int size, int step, int index) {
if(size == 2) {
complex *result;
result = (complex*)malloc(size*sizeof(complex));
result[0] = add(arr[index], arr[index+step]);
result[1] = sub(arr[index], arr[index+step]);
return result;
}
else {
int i;
complex *even, *odd, *result, *mull;
even = _fft(arr, size/2, step*2, index);
odd = _fft(arr, size/2, step*2, index+step);
result = (complex*)malloc(size*sizeof(complex));
mull = (complex*)malloc(size/2*sizeof(complex));
for(i=0;i<size/2;i++) {
mull[i] = mul(odd[i], w(i,size));
}
for(i=0;i<size/2;i++)
result[i] = add(even[i], mull[i]);
for(;i<size;i++)
result[i] = sub(even[i - size/2], mull[i - size/2]);
free(even);
free(odd);
free(mull);
return result;
}
}
complex* fft(complex *arr, int size) {
return (complex*)_fft(arr, size, 1, 0);
}
complex* _ifft(complex *arr, int size, int step, int index) {
if(size == 2) {
complex *result;
result = (complex*)malloc(size*sizeof(complex));
result[0] = add(arr[index], arr[index+step]);
result[1] = sub(arr[index], arr[index+step]);
return result;
}
else {
int i;
complex *even, *odd, *result, *mull;
even = _ifft(arr, size/2, step*2, index);
odd = _ifft(arr, size/2, step*2, index+step);
result = (complex*)malloc(size*sizeof(complex));
mull = (complex*)malloc(size/2*sizeof(complex));
for(i=0;i<size/2;i++)
mull[i] = mul(odd[i], wp(i,size));
for(i=0;i<size/2;i++)
result[i] = add(even[i], mull[i]);
for(;i<size;i++)
result[i] = sub(even[i - size/2], mull[i - size/2]);
free(even);
free(odd);
free(mull);
return result;
}
}
complex* ifft(complex *arr, int size) {
complex *re = _ifft(arr, size, 1, 0);
for(int i=0;i<size;i++){
re[i].real=re[i].real/size;
re[i].im=re[i].im/size;
}
return re;
}
complex** transpose(complex **src, int n, int m) {
complex **result, ***re;
result=(complex**)malloc(sizeof(complex*)*m);
for(int i=0;i<m;i++) {
result[i]=(complex*)malloc(sizeof(complex)*n);
for(int j=0;j<n;j++)
result[i][j]=src[j][i];
}
re=(complex***)&result;
return (complex**)*re;
}
complex** fft_2d(complex** arr, int n, int m) {
complex **arrR, ***r, *temp;
int i, j;
arrR = (complex**)malloc(sizeof(complex*));
for(i=0;i<n;i++) {
arrR[i]=(complex*)fft(arr[i],m);
printf("%d ",i);
}
arrR=(complex**)transpose(arrR,n,m);
malloc(0);
for(i=0;i<m;i++)
arrR[i]=(complex*)fft(arrR[i],n);
arrR=transpose(arrR,n,m);
r=(complex***)&arrR;
return (complex**)*r;
}
complex** ifft_2d(complex** arr, int n, int m) {
complex **arrR, ***r, *temp;
int i, j;
arrR = (complex**)malloc(sizeof(complex*));
for(i=0;i<n;i++)
arrR[i]=(complex*)ifft(arr[i],m);
arrR=(complex**)transpose(arrR,n,m);
malloc(0);
for(i=0;i<m;i++)
arrR[i]=(complex*)ifft(arrR[i],n);
arrR=transpose(arrR,n,m);
r=(complex***)&arrR;
return (complex**)*r;
}
unsigned int** zoom_img(unsigned int **img, int col, int row, int r_col, int r_row) {
int i, j;
complex **mat=(complex**)malloc(sizeof(complex*)*col), **re;
complex **new_re=(complex**)malloc(sizeof(complex*)*(col+2*r_col)), **u;
unsigned int **result=(unsigned int**)malloc(sizeof(unsigned int*)*(col + 2*r_col)), ***z;
for(i=0;i<col;i++)
mat[i]=(complex*)malloc(sizeof(complex)*row);
for (i=0;i<col;i++) {
for (j=0;j<row;j++) {
mat[i][j].real = (float)pow(-1, i+j)*(float)img[i][j];
mat[i][j].im=0;
}
}
re = (complex**)fft_2d(mat, col, row);
for(i=0;i<(col+2*r_col);i++)
new_re[i]=(complex*)malloc(sizeof(complex)*(row+2*r_row));
for(i=0;i<(col+2*r_col);i++) {
for(j=0;j<(row+2*r_row);j++) {
if(i<r_col || i>r_col+col-1 || j<r_row || j>r_row+row-1) {
new_re[i][j].real = 0;
new_re[i][j].im = 0;
}
else
new_re[i][j]=re[i-r_col][j-r_row];
}
}
u = (complex**)ifft_2d(new_re, col+2*r_col, row + 2*r_row);
for(i=0;i<(col+2*r_col);i++) {
result[i]=(unsigned int*)malloc(sizeof(unsigned int)*(row+2*r_row));
for(j=0;j<(row+2*r_row);j++) {
result[i][j] = (unsigned int)u[i][j].real;
}
}
z=&result;
return *z;
}
int main() {
unsigned int i, j, **arr=(unsigned int**)malloc(sizeof(unsigned int*)*2), **result;
for(i=0;i<2;i++) {
arr[i]=(unsigned int*)malloc(sizeof(unsigned int)*2);
for(j=0;j<2;j++) {
arr[i][j] = i+j +1;
}
}
result = zoom_img(arr,2,2,2,2);
return 0;
}/*
int main() {
complex **arr, **result, **re;
arr=(complex**)malloc(sizeof(complex*)*4);
for (int i = 0; i < 4; i++) {
arr[i]=(complex*)malloc(sizeof(complex)*4);
for (int j = 0; j < 4; j++) {
arr[i][j].real = i*j+1.2;
arr[i][j].im=0;
}
}
result = (complex**)fft_2d(arr,4,4);
//malloc(0);
re = (complex**)ifft_2d(result,4,4);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("(%2f) ", arr[i][j].real);
printComplexS(result[i][j]);
printf(" (%2f) ",re[i][j].real);
}
printf("\n");
}
return 0;
}*/
代码有几个问题。
complex** ifft_2d(complex** arr, int n, int m) {
complex **arrR, ***r;
int i;
然后你分配的太少了:
arrR = (complex**)malloc(sizeof(complex*));
上面一行应该是malloc(sizeof(complex*) * n)
。没有 *n
下一行会导致未定义的行为(缓冲区溢出):
for(i=0;i<n;i++)
arrR[i]=(complex*)ifft(arr[i],m);
然后就是这条奇怪的线,这是为什么?
malloc(0);
然后函数的结尾很奇怪(为什么不直接return arrR?):
r=(complex***)&arrR;
return (complex**)*r;
接下来,递归代码(_ifft和_fft)假定size
是2的幂,否则进入无限递归。您应该验证输入。至少断言:
assert(n >= 2);
assert(((n-1) & n ) == 0); // for positive n, assert that it is a power of 2
通过这一行,您可以看到 zoom_img
违反了这一行中的假设:
u = (complex**)ifft_2d(new_re, col+2*r_col, row + 2*r_row);
请注意,在未注释的 main
中,col==2, row==2, r_col==2, r_row==2, 以 size = 结尾= 6,这不是 2 的幂。
一个较小的问题是性能。代码过度使用 malloc
而不是重复使用同一块内存,并查看它的不同区域。这就是经典 FFT 所做的。经典 FFT 也不使用那样的递归,而是使用迭代。
我正在尝试创建一个 zoom_image 函数,该函数使用离散傅立叶变换来缩放灰度图像。如果图像尺寸小于或等于 4*4 但如果尺寸增加,我包含的代码将起作用。它给出 'double free or corruption (out) Aborted (core dumped)' 错误
我已经尝试了我的代码的 fft_d 和 ifft_2d 功能 如果输入大小很小它可以工作 如果输入大小很大它会给出上述错误
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
struct complex{
float real;
float im;
};
typedef struct complex complex;
complex w(int i, int n) {
complex result;
result.real = cos(2*M_PI*i/n);
result.im = -sin(2*M_PI*i/n);
return result;
}
complex wp(int i, int n) {
complex result;
result.real = cos(2*M_PI*i/n);
result.im = sin(2*M_PI*i/n);
return result;
}
complex mul(complex a, complex b) {
complex result;
result.real = a.real*b.real - a.im*b.im;
result.im = a.real*b.im + b.real*a.im;
return result;
}
complex divi(complex a, complex b) {
complex result;
result.real = (a.real*b.real + a.im*b.im)/(b.real*b.real + b.im*b.im);
result.im = (-a.real*b.im + b.real*a.im)/(b.real*b.real + b.im*b.im);
return result;
}
complex add(complex a, complex b) {
complex result;
result.real = a.real+b.real ;
result.im = a.im+b.im;
return result;
}
complex sub(complex a, complex b) {
complex result;
result.real = a.real - b.real;
result.im = a.im - b.im;
return result;
}
void printComplex(complex var) {
printf("%f i%f\n",var.real,var.im);
}
void printComplexS(complex var) {
printf("%f i%f",var.real,var.im);
}
#include<stdio.h>
#include<stdlib.h>
#include"complex.h"
static int gb=0;
complex* _fft(complex *arr, int size, int step, int index) {
if(size == 2) {
complex *result;
result = (complex*)malloc(size*sizeof(complex));
result[0] = add(arr[index], arr[index+step]);
result[1] = sub(arr[index], arr[index+step]);
return result;
}
else {
int i;
complex *even, *odd, *result, *mull;
even = _fft(arr, size/2, step*2, index);
odd = _fft(arr, size/2, step*2, index+step);
result = (complex*)malloc(size*sizeof(complex));
mull = (complex*)malloc(size/2*sizeof(complex));
for(i=0;i<size/2;i++) {
mull[i] = mul(odd[i], w(i,size));
}
for(i=0;i<size/2;i++)
result[i] = add(even[i], mull[i]);
for(;i<size;i++)
result[i] = sub(even[i - size/2], mull[i - size/2]);
free(even);
free(odd);
free(mull);
return result;
}
}
complex* fft(complex *arr, int size) {
return (complex*)_fft(arr, size, 1, 0);
}
complex* _ifft(complex *arr, int size, int step, int index) {
if(size == 2) {
complex *result;
result = (complex*)malloc(size*sizeof(complex));
result[0] = add(arr[index], arr[index+step]);
result[1] = sub(arr[index], arr[index+step]);
return result;
}
else {
int i;
complex *even, *odd, *result, *mull;
even = _ifft(arr, size/2, step*2, index);
odd = _ifft(arr, size/2, step*2, index+step);
result = (complex*)malloc(size*sizeof(complex));
mull = (complex*)malloc(size/2*sizeof(complex));
for(i=0;i<size/2;i++)
mull[i] = mul(odd[i], wp(i,size));
for(i=0;i<size/2;i++)
result[i] = add(even[i], mull[i]);
for(;i<size;i++)
result[i] = sub(even[i - size/2], mull[i - size/2]);
free(even);
free(odd);
free(mull);
return result;
}
}
complex* ifft(complex *arr, int size) {
complex *re = _ifft(arr, size, 1, 0);
for(int i=0;i<size;i++){
re[i].real=re[i].real/size;
re[i].im=re[i].im/size;
}
return re;
}
complex** transpose(complex **src, int n, int m) {
complex **result, ***re;
result=(complex**)malloc(sizeof(complex*)*m);
for(int i=0;i<m;i++) {
result[i]=(complex*)malloc(sizeof(complex)*n);
for(int j=0;j<n;j++)
result[i][j]=src[j][i];
}
re=(complex***)&result;
return (complex**)*re;
}
complex** fft_2d(complex** arr, int n, int m) {
complex **arrR, ***r, *temp;
int i, j;
arrR = (complex**)malloc(sizeof(complex*));
for(i=0;i<n;i++) {
arrR[i]=(complex*)fft(arr[i],m);
printf("%d ",i);
}
arrR=(complex**)transpose(arrR,n,m);
malloc(0);
for(i=0;i<m;i++)
arrR[i]=(complex*)fft(arrR[i],n);
arrR=transpose(arrR,n,m);
r=(complex***)&arrR;
return (complex**)*r;
}
complex** ifft_2d(complex** arr, int n, int m) {
complex **arrR, ***r, *temp;
int i, j;
arrR = (complex**)malloc(sizeof(complex*));
for(i=0;i<n;i++)
arrR[i]=(complex*)ifft(arr[i],m);
arrR=(complex**)transpose(arrR,n,m);
malloc(0);
for(i=0;i<m;i++)
arrR[i]=(complex*)ifft(arrR[i],n);
arrR=transpose(arrR,n,m);
r=(complex***)&arrR;
return (complex**)*r;
}
unsigned int** zoom_img(unsigned int **img, int col, int row, int r_col, int r_row) {
int i, j;
complex **mat=(complex**)malloc(sizeof(complex*)*col), **re;
complex **new_re=(complex**)malloc(sizeof(complex*)*(col+2*r_col)), **u;
unsigned int **result=(unsigned int**)malloc(sizeof(unsigned int*)*(col + 2*r_col)), ***z;
for(i=0;i<col;i++)
mat[i]=(complex*)malloc(sizeof(complex)*row);
for (i=0;i<col;i++) {
for (j=0;j<row;j++) {
mat[i][j].real = (float)pow(-1, i+j)*(float)img[i][j];
mat[i][j].im=0;
}
}
re = (complex**)fft_2d(mat, col, row);
for(i=0;i<(col+2*r_col);i++)
new_re[i]=(complex*)malloc(sizeof(complex)*(row+2*r_row));
for(i=0;i<(col+2*r_col);i++) {
for(j=0;j<(row+2*r_row);j++) {
if(i<r_col || i>r_col+col-1 || j<r_row || j>r_row+row-1) {
new_re[i][j].real = 0;
new_re[i][j].im = 0;
}
else
new_re[i][j]=re[i-r_col][j-r_row];
}
}
u = (complex**)ifft_2d(new_re, col+2*r_col, row + 2*r_row);
for(i=0;i<(col+2*r_col);i++) {
result[i]=(unsigned int*)malloc(sizeof(unsigned int)*(row+2*r_row));
for(j=0;j<(row+2*r_row);j++) {
result[i][j] = (unsigned int)u[i][j].real;
}
}
z=&result;
return *z;
}
int main() {
unsigned int i, j, **arr=(unsigned int**)malloc(sizeof(unsigned int*)*2), **result;
for(i=0;i<2;i++) {
arr[i]=(unsigned int*)malloc(sizeof(unsigned int)*2);
for(j=0;j<2;j++) {
arr[i][j] = i+j +1;
}
}
result = zoom_img(arr,2,2,2,2);
return 0;
}/*
int main() {
complex **arr, **result, **re;
arr=(complex**)malloc(sizeof(complex*)*4);
for (int i = 0; i < 4; i++) {
arr[i]=(complex*)malloc(sizeof(complex)*4);
for (int j = 0; j < 4; j++) {
arr[i][j].real = i*j+1.2;
arr[i][j].im=0;
}
}
result = (complex**)fft_2d(arr,4,4);
//malloc(0);
re = (complex**)ifft_2d(result,4,4);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("(%2f) ", arr[i][j].real);
printComplexS(result[i][j]);
printf(" (%2f) ",re[i][j].real);
}
printf("\n");
}
return 0;
}*/
代码有几个问题。
complex** ifft_2d(complex** arr, int n, int m) {
complex **arrR, ***r;
int i;
然后你分配的太少了:
arrR = (complex**)malloc(sizeof(complex*));
上面一行应该是malloc(sizeof(complex*) * n)
。没有 *n
下一行会导致未定义的行为(缓冲区溢出):
for(i=0;i<n;i++)
arrR[i]=(complex*)ifft(arr[i],m);
然后就是这条奇怪的线,这是为什么?
malloc(0);
然后函数的结尾很奇怪(为什么不直接return arrR?):
r=(complex***)&arrR;
return (complex**)*r;
接下来,递归代码(_ifft和_fft)假定size
是2的幂,否则进入无限递归。您应该验证输入。至少断言:
assert(n >= 2);
assert(((n-1) & n ) == 0); // for positive n, assert that it is a power of 2
通过这一行,您可以看到 zoom_img
违反了这一行中的假设:
u = (complex**)ifft_2d(new_re, col+2*r_col, row + 2*r_row);
请注意,在未注释的 main
中,col==2, row==2, r_col==2, r_row==2, 以 size = 结尾= 6,这不是 2 的幂。
一个较小的问题是性能。代码过度使用 malloc
而不是重复使用同一块内存,并查看它的不同区域。这就是经典 FFT 所做的。经典 FFT 也不使用那样的递归,而是使用迭代。