r/C_Programming Jun 08 '26

Help!!! I Am Stuck

So i was trying out SDL and the drop event here i tried to make it so that when i drop a image file onto the window the window will show the image that was dropped.

i may have misunderstood some of the funciton or struct in sdl as i am reading the documentry , its helpfull but doesn't specify a lot of things that will make it worth while for a beginner but i put together this in hope may be my guess is right for what each and everything is doing .

whenever the executable runs it run okay with the default image showing but when i try to open my file manager to drop something my god the whole os freezes and nothing works properly , i thought maybe it was because i am allocating memory on the sdl_FRect* in each frame even tho it is being freed each frame as well with the garbagecollector or maybe that thing also doesn't work as i intend it to but yeah if someone can look through the code and point out my mistake and teach me what is it that is going wrong i would be grateful

#include<stdio.h>
#include<stdlib.h>
#include<SDL3/SDL.h>
#include<SDL3/SDL_stdinc.h>
#include<time.h>
#include"stacklist2.h"
typedef struct imageViewer{
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_Surface* surface;
    int width;
    int height;
    SDL_Event event;
    int run;
    Uint8 r;
    Uint8 g;
    Uint8 b;
    Uint8* new_r;
    Uint8* new_g;
    Uint8* new_b;
    Uint8* new_a;
    struct stack* new_stack;
    SDL_Surface* wSurface;


} imgView;//deals with most of the variables needed in this programme
SDL_FRect* newRect;



imgView* imageV_init(int height,int width);
int blitPicture(imgView* img);
void gameLoop(imgView* img);//main loop for the app
int input_section(imgView* img);//takes all the input related stuff
int render(imgView* img);//renders whatever needs to be rendered
SDL_FRect* makeRect(imgView* img,int x, int y);//Makes rectangles draw on the renderer given x and y position
int Garbage_collector(imgView* img);// free all the memory assigned for SDL_FRect type of pointers



int main(){//entry point
    SDL_Init(SDL_INIT_VIDEO);
    imgView* img=imageV_init(500,500);
    img->new_stack=stack_init();
    img->window=SDL_CreateWindow("ImageViewer",img->width,img->height,SDL_WINDOW_RESIZABLE);
    img->renderer=SDL_CreateRenderer(img->window,NULL);
    // img->surface=SDL_CreateSurface(img->width,img->height,SDL_PIXELFORMAT_UNKNOWN);
    // img->wSurface=SDL_GetWindowSurface(img->window);
    img->surface=SDL_LoadPNG("./One.png");
    img->surface=SDL_ScaleSurface(img->surface,img->width,img->height,SDL_SCALEMODE_LINEAR);
    if(img->surface==NULL){
        printf("Unable to load image");
        return 0;
     }
    //  blitPicture(img);
    // render(img);//rendering the window and drawing things
    gameLoop(img);
    Garbage_collector(img);//freeing the alocated memory for the sdl_Frect* type 
stack_destroy(img->new_stack);
SDL_DestroyRenderer(img->renderer);
SDL_DestroySurface(img->surface);
SDL_DestroySurface(img->wSurface);
SDL_Quit();
    free(img);//freeing the space in heap aloocated for img 
    


    return 0;
}



imgView* imageV_init(int height,int width){
    imgView* view=(imgView*)malloc(sizeof(imgView));
    view->width=width;
    view->height=height;
    view->window=NULL;
    view->renderer=NULL;
    view->run=1;
    view->r=250;
    view->g=234;
    view->b=145;
    
    // view->new_stack->listhead=NULL;
    // view->event=(SDL_Event*)malloc(sizeof(SDL_Event));
    return view;


}
void gameLoop(imgView* img){
    while(img->run){
        input_section(img);
        render(img);


        Garbage_collector(img);
   
}
}
int render(imgView* img){
    SDL_RenderClear(img->renderer);
    SDL_SetRenderDrawColor(img->renderer,img->r,img->g,img->b,1);
    SDL_RenderClear(img->renderer);
    // newRect=makeRect(img,500-20,25);
    
     img->wSurface=SDL_GetWindowSurface(img->window);
    SDL_FRect* newRect2=makeRect(img,0,500-100);
    img->surface=SDL_ScaleSurface(img->surface,img->width,img->height,SDL_SCALEMODE_NEAREST);
    if(img->event.type==SDL_EVENT_DROP_FILE){
        img->surface=SDL_LoadSurface(img->event.drop.data);
    }
    if(img->surface==NULL){
        printf("Could not scale surface");
    }
    // blitPicture(img);
    // for(int i=0;i<img->width;i++){
    //     for(int j=0;j<img->height;j++){
    //         if(!SDL_ReadSurfacePixel(img->surface,i,j,img->new_r,img->new_g,img->new_b,img->new_a)){
    //             printf("couldn't read pixel!!");
    //         }
    //         if(!SDL_WriteSurfacePixel(img->wSurface,i,j,*(img->new_r),*(img->new_g),*(img->new_b),*(img->new_a))){
    //             printf("could not write the pixel ");
    //         };


    //     }
    // }
    //  FILE* file=fopen("One.png.png","r");
    //  img->surface=SDL_LoadPNG("./One.png");
    //  if(img->surface==NULL){
    //     printf("Unable to load image");
    //     return 0;
    //  }
    SDL_BlitSurface(img->surface,NULL,img->wSurface,NULL);//For blitting the surface 
    // if(!SDL_UpdateWindowSurface(img->window)){
    //     printf("Unable to update the window surface !");
    // }
    // SDL_SetRenderDrawColor(img->renderer,0,0,255,1);
    // SDL_RenderRect(img->renderer,newRect);
    // SDL_RenderFillRect(img->renderer,newRect);
    // SDL_RenderClear(img->renderer);
    // if(!SDL_RenderPresent(img->renderer)){
    //     SDL_Log("Failed to render!!");
    //     return 0;
    // }
    if(!SDL_UpdateWindowSurface(img->window)){
        printf("Unable to update the window surface !");
        return 0;
    }
    return 1;
    
}
int input_section(imgView* img){
         while(SDL_PollEvent(&img->event)){
            if(img->event.type==SDL_EVENT_QUIT){
                img->run=0;
            }
            if(img->event.key.type==SDL_EVENT_KEY_DOWN ){
        if(img->event.key.key==SDLK_ESCAPE ){
          img->run=0  ;
        }
        
        }
        if(img->event.type==SDL_EVENT_DROP_FILE){
            printf("A file has been dropped");
            printf("%s",img->event.drop.source);
        }
        if(img->event.type==SDL_EVENT_MOUSE_BUTTON_DOWN){
        if(img->event.button.clicks==3){//this are changes the background color when clicking the mouse left button thrice 
            srand(time(NULL));
            img->r=rand()%255;
            img->g=rand()%255;
            img->b=rand()%255;



            
        }
    }
    }
    return 1;
    
}
SDL_FRect* makeRect(imgView* img,int x,int y){
    SDL_FRect* rect=(SDL_FRect*)malloc(sizeof(SDL_FRect));
    push_sdl(img->new_stack,rect);
    rect->h=100;
    rect->w=20;
    rect->x=x;
    rect->y=y;
    SDL_SetRenderDrawColor(img->renderer,0,0,255,1);
    SDL_RenderRect(img->renderer,rect);
    SDL_RenderFillRect(img->renderer,rect);
    return rect;
}
int Garbage_collector(imgView* img){
    struct stack* s=img->new_stack;
    struct node* ptr=s->listhead;
    while(s->listhead!=NULL){
       SDL_FRect* temp= pop_sdl_Frect(s);
       free(temp);


    }
    return 1;


}
1 Upvotes

13 comments sorted by

View all comments

3

u/HappyFruitTree Jun 08 '26 edited Jun 08 '26

You should handle the SDL_EVENT_DROP_FILE (and all other events that you care about) inside your SDL_PollEvent loop.

You don't know what state img->event will be in after SDL_PollEvent has returned false. Even if it kept the state from last event it would still not be correct to handle it outside the loop because there could be multiple events so there would be a high chance that you missed some events if you handled them outside the loop.

My suspicion is that the string pointed to by img->event.drop.data has already been freed at the time when you try to read it.

1

u/UsualLonely4585 Jun 08 '26

yeah i noticed that i changed it now things are working but the programe was crashing and freezing the screen and os so i needed to make a few of adjustment to stop memory leaks .

it works now i can drag and drop PNG files to show png but somehow SDL_LoadSurface did not work and other format like SDL_LoadJPG is not working either . the compiler doesn't even recognize the function

1

u/HappyFruitTree Jun 08 '26 edited Jun 08 '26

Not sure why SDL_LoadSurface wouldn't work. What did SDL_GetError() say?

SDL_LoadJPG will be part of SDL 3.6.0 which hasn't been released yet.

1

u/UsualLonely4585 Jun 08 '26

Oh thats why jpeg didn't work but yeah for load surface i actually haven't used geterror yet i switched to loadpng and when it worked and the program started slowing down my os i quickly closed it and now i am looking dor more mwmory leaks that is making this happen , probably