gpt4 book ai didi

c - pb用C程序: double free or corruption (! prev)

转载 作者:太空宇宙 更新时间:2023-11-04 08:24:31 25 4
gpt4 key购买 nike

几年前,当 Benoit Mandelbrot 去世时,我决定制作一个小程序来计算并查看他著名的分形集。很多年前我就做过(用turbo pascal语言)——这段时间,微积分花了一个晚上。所以我决定学一点C语言。使用 code::blocks 和 SDL 库(以及许多帮助),我终于编写了一个程序,我可以看到集合,并用鼠标放大内部。效果很好,我在 window 下。做同样的工作只需要 5 秒钟,而不是一晚上的微积分。

最近我决定探索 linux,安装了与 SDL 相同的 IDE。程序编译正常。它开始运行,突然,当我使用鼠标(左键上下单击以选择要放大的新方形区域)时,程序停止了。

消息是:

double free or corruption (!prev)

奇怪的是我在windows下运行代码从来没有出现过。所以这对我来说是一件神秘的事情。我不知道这里的双重免费腐败是什么意思。

为了更好的帮助你最终可以发给我,我加入了程序的代码(不完美)。也许有人可以找到问题所在...该程序是为在 1680x1050 像素的屏幕上显示而编写的。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <SDL/SDL.h>
//#include <SDL/SDL_ttf.h>

#define MAXITERATIONS 2000
#define CONST_DIVERGENCE 4

#define LONGUEUR_ECRAN 1680 //ajout d'une zone d'information et d'interaction de 630 pixels de large à droite de l'image.
#define LARGEUR_ECRAN 1050 // côté du carré où l'image est calculée.


int i , j ; /* i variable écran qui parcourt les abscisses entre 0 et LARGEUR_ECRAN
j les ordonnées entre 0 et LARGEUR_ECRAN */
int n ,t ; // itérations pour le calcul de convergence
int color,color1,color2,color3 ; //variable pour la couleur

int continuer = 1;
int recalculer = 1;
int recommencer = 1;

double XDEBUT = -2.05; // coordonnées du point de départ en haut à gauche du carré du plan complexe
double YDEBUT = -1.35;
double DELTA = 2.7 ; // longueur du côté du carré du plan complexe au départ
double xC =0 , yC = 0 ; // coordonnées du point du plan où on effectue les calculs
double xZ , yZ ; // coordonnées pour le calcul de la convergence
double xT = 0 ; // valeur temporaire d'allocation

double xTemp1 =0, yTemp1 = 0 ;
double xTemp2 =0, yTemp2 = 0 ;

int xTemoinDebut =1065; //variables pour positionner les cadres dans le Mandel témoin
int yTemoinDebut =15; //
int deltaTemoin =600; //

int x_1 , y_1; //variables pour positionner le cadre de zoom dans le grand Mandel
int x_2 , y_2; //
int xdebut , ydebut ; //
int delta; //

void placerPoint(SDL_Surface *surface, int x, int y, Uint32 pixel);
void petitMandel ();

int main(int argc, char *argv[])
{
while (recommencer == 1)
{
recommencer = 0;
recalculer =1;
continuer =1;
double XDEBUT = -2.05; // coordonnées du point de départ en haut à gauche du carré du plan complexe
double YDEBUT = -1.35;
double DELTA = 2.7 ; // longueur du côté du carré du plan complexe au départ

int xTemoinDebut =1065; //variables pour positionner les cadres dans le Mandel témoin
int yTemoinDebut =15; //
int deltaTemoin =600; //

double xC =0 , yC = 0 ; // coordonnées du point du plan où on effectue les calculs
double xZ , yZ ; // coordonnées pour le calcul de la convergence
double xT = 0 ; // valeur temporaire d'allocation
double xTemp1 =0, yTemp1 = 0 ;
double xTemp2 =0, yTemp2 = 0 ;
double tableauX [LARGEUR_ECRAN]= {0}; //tableau pour enregistrer les coordonnées réelles où on calcule
double tableauY [LARGEUR_ECRAN] = {0}; //


SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *ecran = NULL,*rectangle=NULL/*,*texte = NULL*/;
// SDL_Event event;
SDL_Rect position;
ecran = SDL_SetVideoMode(LONGUEUR_ECRAN,LARGEUR_ECRAN, 32, SDL_HWSURFACE | SDL_FULLSCREEN); // mode vidéo : écran complet
SDL_LockSurface(ecran);
// SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); // remplissage de l'écran en noir
// TTF_Font *police = NULL;
// SDL_Color couleurBleue = {0,0,255};
// TTF_Init();

// test d'erreur d'initialisation
/* if (TTF_Init () == -1)
{
fprintf(stderr, "Erreur d'initialisation de TTF_Init : %s \n",TTF_GetError ());
exit (EXIT_FAILURE);
}*/

/* TTF_Font *police = NULL;
SDL_Color couleurBleue = {0,0,255};
police = TTF_OpenFont("ankecall.ttf",20); police = TTF_OpenFont ("angelina.ttf",65);
texte = TTF_RenderText_Blended (police, "Voyage chez Mandelbrot ", couleurBleue);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}

position.x = 1060;
position.y = 630;
SDL_BlitSurface (texte, NULL, ecran, &position);
SDL_Flip(ecran);
}
SDL_FreeSurface(texte);
TTF_CloseFont(police);
TTF_Quit ();
*/

petitMandel(); //commande pour calculer un petit mandel témoin et un trait rouge

while (recalculer == 1)
{
for ( j = 0 ; j < LARGEUR_ECRAN ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/LARGEUR_ECRAN;
tableauY[j] = yC;
}
for ( i = 0 ; i < LARGEUR_ECRAN ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/LARGEUR_ECRAN;
tableauX [i] = xC;
}

for ( j = 0 ; j < LARGEUR_ECRAN ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/LARGEUR_ECRAN;
for ( i = 0 ; i < LARGEUR_ECRAN ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/LARGEUR_ECRAN;
n = 0 ; // initialisation du compteur de calcul
xZ = 0 ;
yZ = 0 ;
xT = 0 ;
while ( xZ*xZ + yZ*yZ < CONST_DIVERGENCE && n < MAXITERATIONS) /* boucle de calcul
elle s'arretera si xZ²+yZ² >= 4 ou si on a atteint le maximum d'itérations*/
{
xT = xZ ;// variable temporaire pour le calcul de yZ
xZ = xZ*xZ - yZ*yZ + xC ;
yZ = 2*yZ*xT + yC ;
n ++;
}

if (n< MAXITERATIONS) // On est en dehors de l'ensemble : mettre en gris
placerPoint(ecran,i,j,SDL_MapRGB(ecran->format,n,n,n));
else // On est dans l'ensemble : mettre en noir.
placerPoint(ecran,i,j,SDL_MapRGB(ecran->format,0,0,0));
}
}
SDL_UnlockSurface(ecran);
SDL_Flip(ecran);

recalculer = 0;

//Gestion des choix:
SDL_Event event;
while (continuer & (recalculer == 0))
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;

case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) //si clic gauche enfoncé
{
position.x = event.button.x;
position.y = event.button.y;
xTemp1 = tableauX [position.x];
yTemp1 = tableauY [position.y];
x_1 = position.x;
y_1 = position.y;
}
break;

case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_LEFT) //si clic gauche relaché
{
position.x = event.button.x;
position.y = event.button.y;
xTemp2 = tableauX [position.x];
yTemp2 = tableauY [position.y];
x_2 = position.x;
y_2 = position.y;

if (xTemp1 <xTemp2)
{
XDEBUT = xTemp1;
xdebut = x_1;
}
else
{
XDEBUT = xTemp2;
xdebut = x_2;
}
if (yTemp1<yTemp2)
{
YDEBUT = yTemp1;
ydebut = y_1;
}
else
{
YDEBUT = yTemp2;
ydebut = y_2;
}
if (fabs(xTemp1-xTemp2)<fabs(yTemp1-yTemp2))
{
DELTA = fabs(yTemp1-yTemp2);
delta = fabs(y_1-y_2);
}
else
{
DELTA = fabs(xTemp1-xTemp2);
delta = fabs(x_1-x_2);
}
// dessin du cadre blanc pour zoomer dans l'image principale
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, delta, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE,delta, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, delta, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut + delta; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, delta, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut + delta;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

//dessin du cadre dans le mandelbrot témoin

xTemoinDebut = floor(xdebut*deltaTemoin/1050) + xTemoinDebut;
yTemoinDebut = floor(ydebut*deltaTemoin/1050) + yTemoinDebut;
deltaTemoin = floor(delta*deltaTemoin/1050);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, deltaTemoin, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, deltaTemoin, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, deltaTemoin, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut + deltaTemoin; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, deltaTemoin, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut + deltaTemoin;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);

recalculer = 1;
}
break;

case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
continuer = 0 ;
if (event.key.keysym.sym == SDLK_r)
{
recommencer = 1 ;
recalculer = 0;
continuer =0;
}
if (event.key.keysym.sym == SDLK_s)
SDL_SaveBMP(ecran , "Mandel_50.bmp" ); // Enregistrement de l'image dans un fichier .bmp

break;
}
}
SDL_FreeSurface(rectangle); // Libération de la surface
}
}
SDL_Quit();
return EXIT_SUCCESS;

}
void petitMandel ()
{
int x=0,y=0;
SDL_Surface *ecran ;
ecran = SDL_GetVideoSurface();
SDL_LockSurface(ecran);

// trait rouge à droite de l'image
for (j=5; j<=1044; j++)
{
x = LARGEUR_ECRAN +5 ;
y = j ;
placerPoint(ecran,x,y,SDL_MapRGB(ecran->format,200,0,0));
}
SDL_Flip(ecran);


// instructions pour placer un petit Mandelbrot témoin dans la fenêtre "interactive"
for ( j = 0 ; j < 600 ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/600;
for ( i = 0 ; i < 600 ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/600;
n = 0 ; // initialisation du compteur de calcul
xZ = 0 ;
yZ = 0 ;
xT = 0 ;
while ( xZ*xZ + yZ*yZ < CONST_DIVERGENCE && n < 500) /* boucle de calcul
elle s'arretera si xZ²+yZ² >= 4 ou si on a atteint le maximum d'itérations*/
{
xT = xZ ;// variable temporaire pour le calcul de yZ
xZ = xZ*xZ - yZ*yZ + xC ;
yZ = 2*yZ*xT + yC ;
n ++;
}
if (n< 500)
{
x = i + 1065 ; // Coordonnées du point à placer
y = j + 15;
color = floor (255-255*log(1+n*255/500)/log(256)); // calcul pour un dégradé plus progressif*/
placerPoint(ecran,x,y,SDL_MapRGB(ecran->format,color,color,color));
}
}
}
SDL_UnlockSurface(ecran);
SDL_Flip(ecran);
}

void placerPoint(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;

Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}

最佳答案

看起来您在第 309 行额外释放了 SDL_Surface 指针“矩形”一次。如果您对该行发表评论,它运行良好。

当代码进入 switch 语句的“SDL_MOUSEBUTTONUP”情况时,它释放矩形,然后在第 309 行再次释放它。

关于c - pb用C程序: double free or corruption (! prev),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31297095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com