Thread: Need help with program that crashes - probably an allocation problem

  1. #1
    Registered User
    Join Date
    Feb 2017
    Posts
    11

    Need help with program that crashes - probably an allocation problem

    Hello everyone , i have tried everything (or so i think) to solve this problem and keep the program logic intact (allocate memory dynamically while everything is unknown [string length and array size alike]).The problem seems to be happening at function GetDirectoryFiles(...) , where i believe i am making some mistake with the allocation of memory , but i just cant find it.The program should take an unknown size string from the user (movies directory / path) , then it should open and read the directory if it exists and then store all the names of the files(filenames) that exist in this directory.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <dirent.h>
    
    
    #define INITIAL_STRING_SIZE 64
    #define INITIAL_STRING_ARRAY_SIZE 16
    
    
    char* ReadDirectory();
    char** GetDirectoryFiles(char *directory,int *numberoffiles);
    void DeleteDirectory(char **dir);
    void DeleteFilenames(char ***filenames,int size);
    char* ReallocOrFreeString(char *sp,size_t sz);
    void ErrorMessage(const char *msg);
    
    
    int main()
    {
        int number,i;
        char *maindir = NULL,**mainfilenames = NULL;
    
    
        maindir = ReadDirectory();
    
    
        mainfilenames = GetDirectoryFiles(maindir,&number);
    
    
        for(i=0;i<number;i++)
        {
            printf("%s\n",mainfilenames[i]);
        }
    
    
        DeleteDirectory(&maindir);
        DeleteFilenames(&mainfilenames,number);
    
    
        system("PAUSE");
        return 0;
    }
    
    
    char* ReadDirectory()
    {
        int c,size = 0,allocated = INITIAL_STRING_SIZE;
        char *maindir = NULL;
    
    
        maindir = malloc(allocated * sizeof(char));
    
    
        if(maindir == NULL)
        {
            ErrorMessage("ReadDirectory 1");
        }
    
    
        printf("Give the directory where the movies are: ");
    
    
        while((c = getchar()) != EOF && c != '\n')
        {
            if(size == allocated - 1)
            {
                maindir = ReallocOrFreeString(maindir,(allocated *= 2) * sizeof(char));
    
    
                if(maindir == NULL)
                {
                    ErrorMessage("ReadDirectory 2");
                }
            }
    
    
            maindir[size] = c;
    
    
            size++;
        }
    
    
        maindir[size] = '\0';
    
    
        return ReallocOrFreeString(maindir,size+1);
    }
    
    
    char** GetDirectoryFiles(char *directory,int *numberoffiles)
    {
        char **filenames = NULL;
        struct dirent *dent;
        DIR *dir;
        int i;
    
    
        if((dir = opendir(directory)) == NULL)
        {
            ErrorMessage("GetDirectoryFiles 1");
        }
    
    
        *numberoffiles = 0;
    
    
        while((dent = readdir(dir)) != NULL)
        {
            if(!strcmp(dent->d_name,".") || !strcmp(dent->d_name,".."))
            {
                continue;
            }
    
    
            (*numberoffiles)++;
        }
    
    
        filenames = malloc(*numberoffiles * sizeof(char*));
    
    
        if(filenames == NULL)
        {
            ErrorMessage("GetDirectoryFiles 2");
        }
    
    
        closedir(dir);
    
    
        if((dir = opendir(directory)) == NULL)
        {
            ErrorMessage("GetDirectoryFiles 1");
        }
    
    
        while((dent = readdir(dir)) != NULL)
        {
            if(!strcmp(dent->d_name,".") || !strcmp(dent->d_name,".."))
            {
                continue;
            }
    
    
            filenames[*numberoffiles] = malloc((strlen(dent->d_name) + 1) * sizeof(char));
    
    
            if(filenames[*numberoffiles] == NULL)
            {
                ErrorMessage("GetDirectoryFiles 3");
            }
    
    
            strcpy(filenames[*numberoffiles],dent->d_name);
        }
    
    
        closedir(dir);
    
    
        for(i=0;i<*numberoffiles;i++)
        {
            printf("%s\n",filenames[i]);
        }
    
    
        return filenames;
    }
    
    
    void DeleteDirectory(char **dir)
    {
        free(*dir);
        *dir = NULL;
    }
    
    
    void DeleteFilenames(char ***filenames,int size)
    {
        int i;
    
    
        for(i=0;i<size;i++)
        {
            free((*filenames)[i]);
        }
    
    
        free(*filenames);
        *filenames = NULL;
    }
    
    
    char* ReallocOrFreeString(char *sp,size_t sz)
    {
        char *p;
    
    
        p = realloc(sp,sz);
    
    
        if(p == NULL)
        {
            free(sp);
        }
    
    
        return p;
    }
    
    
    void ErrorMessage(const char *msg) {
        fprintf(stderr, "Error: %s\n", msg);
        exit(EXIT_FAILURE);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,625
    Well let me leave this gdb run for you to ponder over.
    Code:
    $ gdb -q ./a.out
    Reading symbols from ./a.out...done.
    (gdb) run
    Starting program: /home/sc/Documents/a.out 
    Give the directory where the movies are: .
    
    Program received signal SIGSEGV, Segmentation fault.
    strlen () at ../sysdeps/x86_64/strlen.S:106
    106	../sysdeps/x86_64/strlen.S: No such file or directory.
    (gdb) bt
    #0  strlen () at ../sysdeps/x86_64/strlen.S:106
    #1  0x00007ffff7a7d69c in _IO_puts (str=0x0) at ioputs.c:35
    #2  0x0000000000400d78 in GetDirectoryFiles (directory=0x603010 ".", numberoffiles=0x7fffffffddf0)
        at foo.c:165
    #3  0x0000000000400a0e in main () at foo.c:28
    (gdb) up
    #1  0x00007ffff7a7d69c in _IO_puts (str=0x0) at ioputs.c:35
    35	ioputs.c: No such file or directory.
    (gdb) up
    #2  0x0000000000400d78 in GetDirectoryFiles (directory=0x603010 ".", numberoffiles=0x7fffffffddf0)
        at foo.c:165
    165	        printf("%s\n",filenames[i]);
    (gdb) print i
    $1 = 0
    (gdb) print filenames[i]
    $2 = 0x0
    (gdb) print *numberoffiles
    $3 = 1354
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Feb 2017
    Posts
    11

    Thumbs up

    Quote Originally Posted by Salem View Post
    Well let me leave this gdb run for you to ponder over.
    Code:
    $ gdb -q ./a.out
    Reading symbols from ./a.out...done.
    (gdb) run
    Starting program: /home/sc/Documents/a.out 
    Give the directory where the movies are: .
    
    Program received signal SIGSEGV, Segmentation fault.
    strlen () at ../sysdeps/x86_64/strlen.S:106
    106    ../sysdeps/x86_64/strlen.S: No such file or directory.
    (gdb) bt
    #0  strlen () at ../sysdeps/x86_64/strlen.S:106
    #1  0x00007ffff7a7d69c in _IO_puts (str=0x0) at ioputs.c:35
    #2  0x0000000000400d78 in GetDirectoryFiles (directory=0x603010 ".", numberoffiles=0x7fffffffddf0)
        at foo.c:165
    #3  0x0000000000400a0e in main () at foo.c:28
    (gdb) up
    #1  0x00007ffff7a7d69c in _IO_puts (str=0x0) at ioputs.c:35
    35    ioputs.c: No such file or directory.
    (gdb) up
    #2  0x0000000000400d78 in GetDirectoryFiles (directory=0x603010 ".", numberoffiles=0x7fffffffddf0)
        at foo.c:165
    165            printf("%s\n",filenames[i]);
    (gdb) print i
    $1 = 0
    (gdb) print filenames[i]
    $2 = 0x0
    (gdb) print *numberoffiles
    $3 = 1354
    Thank you for your help (btw i like your reply , because it should make me find my fault on my own) , howewer i dont know how to read that , nor do i know were to learn to read it.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Salem was using a program called gdb to track down the source of your crash. The output he has posted is called a backtrace, which is basically a listing of all the function calls made up to the point of the crash.

    With a little bit of googling there are explanations of gdb out there.
    RMS's gdb Tutorial: How do I use the call stack?

    The output Salem gave you should help you with the problem... you'll have to fix the filenames array to get anywhere close to a fix.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 11-23-2015, 02:55 PM
  2. Program crashes
    By mallison359 in forum C Programming
    Replies: 14
    Last Post: 10-31-2014, 06:49 AM
  3. My program crashes :|
    By Testify in forum C++ Programming
    Replies: 12
    Last Post: 06-27-2007, 11:48 AM
  4. Program crashes, why?
    By Mahdi123 in forum C Programming
    Replies: 5
    Last Post: 04-18-2007, 02:56 PM
  5. Odd program crashes
    By Mithoric in forum Windows Programming
    Replies: 3
    Last Post: 03-20-2004, 11:37 PM

Tags for this Thread