I've been learning about dynamic memory allocation in C and practicing it in code. While I think I've allocated the memory properly, I could be wrong about that. So any useful comments about that are fine (but please explain any suggestions so I can understand).
I've written a C program to first get a list of files in the current working directory, and write to each one. But the loop is seeing NULL before it's finished getting though all of the files. It was segfaulting before that, but I managed to fix that. Where it was not pointing to the correct part of memory, which was causing functions like fopen() to not get any filenames.
But while I can print out a list of files, the loop in writeToFiles() is just not completing the list of filenames that I've dynamically allocated whenever I use pretty much any of f* (file related) C library functions.
I've managed to fix all compilers errors and warning messages I was getting, but I really have no idea what's going on with it now. What I think is happening is that the pointer pointing to the struct member called filename isn't at the start of the pointer array. I'm pretty sure my buildFileList() function is fine and it IS working correctly. So do I need to "rewind" the pointer or something ?
If I could politely ask those that wish to respond to be as clear and complete as possible in any answers given. As I'm clearly missing something here, but I have no idea what.
WARNING: The following code if run will OVERWRITE the contents of the current working directory.
I've posted my code below:
___dyn_char_mem_alloc.c
char *___dyn_char_mem_alloc(size_t buffSize) {    
    
    // allocate char memory with malloc() for char *        
   
    char *ptr = malloc(buffSize+1);
   
    //printf("buffSize (char): %d\n", buffSize);
    
    // if malloc returns a pointer that is not NULL, we return it to the caller
    if (ptr != NULL) {
        // puts("malloc() pointer returned (char *)\n");
        // printf("ptr in ___dyn_char_mem_alloc() function = %p\n");
        return ptr;
    } else {       
        // puts("malloc() call failed!\n");
        return NULL; 
   }
}
___dyn_char_mem_alloc.h
#include <stdio.h>
#include <stdlib.h> // for malloc()
char *___dyn_char_mem_alloc(size_t buffSize);
___dyn_struct_mem_alloc.c
#include "___dyn_struct_mem_alloc.h"
struct filepath *___dyn_struct_mem_alloc(size_t buffSize) {
        
    // allocate char memory with malloc() for struct
    
    struct filepath *t_filepath = malloc(buffSize);   
    
    // if malloc returns a pointer that is not NULL, we return it to the caller
    if (t_filepath != NULL) {      
        return t_filepath;
    } else {       
        // puts("malloc() call failed!\n");
        return NULL;
    }
}
___dyn_struct_mem_alloc.h
#include <stdio.h>
#include <stdlib.h> // for malloc()
#include <linux/limits.h>
//struct filepath *___dyn_struct_mem_alloc(size_t buffSize);
struct filepath {
    char *path[PATH_MAX];
    char *filename[FILENAME_MAX];
};
build_file_list.c
struct filepath *buildFileList(void) {
    
    DIR *d = opendir(".");
    struct dirent *dir;
    struct stat stats;
    //struct filepath *t_filepath = malloc(sizeof(struct filepath));
    struct filepath *t_filepath = ___dyn_struct_mem_alloc(sizeof(struct filepath)); 
    int i = 0, strLength = 0, totalNumFiles = 0;        
    const char *pDirFsPtr = "..", *curWorkDirFsPtr = ".";        
    
    while (((dir = readdir(d)) != NULL)) {
        
        if ( (!strcmp(dir->d_name, pDirFsPtr)) || (!strcmp(dir->d_name, curWorkDirFsPtr)) )  {              
            continue;
        } else {              
            // check if it's a directory and if so skip it              
            stat(dir->d_name, &stats);
            if (!S_ISDIR(stats.st_mode)) {
                // get length of filename
                strLength = strlen(dir->d_name);
                  
                // allocate some memory for the filename               
                //t_filepath->filename[i] = malloc(sizeof(char) * (strLength+1));
                t_filepath->filename[i] = ___dyn_char_mem_alloc(strLength+1);                
                  
                // let's copy each filename from the dirent structure's d_name member to our newly dynamically allocated memory                 
                //  t_filepath->filename[i]=(dir->d_name); // doesn't matter if i use strcpy() below instead or not - same problem
                strcpy(t_filepath->filename[i], dir->d_name);                  
                //  printf("filepath->filename[%d] name: %s | ptr: %p \n",i, t_filepath->filename[i], t_filepath->filename[i]); // works no problem
                  
                totalNumFiles++;                  
            }                                         
        }
        ++i;
    }    
    closedir(d);
    
    printf("t_filepath struct ptr from buildFileList(): %p\n",  t_filepath);
    printf("t_filepath->filename struct ptr from buildFileList(): %p\n",  t_filepath->filename);
        
    #ifdef DEBUG    
    printf("\nTotal number of files in dir: %d\n\n", totalNumFiles);
    #endif
    
    #ifdef DEBUG
    int k = 0;
    while (t_filepath->filename[k] != NULL) {
        printf("t_filepath->filename[%d] name: %s | ptr addr: %p \n",k, t_filepath->filename[k], t_filepath->filename[k]);
        ++k;
    }
    #endif
    
    return t_filepath;
}
build_file_list.h
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <linux/limits.h>
struct filepath *buildFileList(void);
char *___dyn_char_mem_alloc(size_t buffSize);
struct filepath *___dyn_struct_mem_alloc(size_t buffSize);
struct filepath {
    char *path[PATH_MAX];
    char *filename[FILENAME_MAX];
};
main.c
#include "main.h"
int main(int argc, char *argv[]) {
        
    //TODO: add a check for command-line args    
       
    someOtherFunction();
        
    return 0;
}
main.h
#include <stdio.h>
int someOtherFunction(void);
some_other_function.c
#include "some_other_function.h"
int someOtherFunction(void) {
    
    struct filepath *t_filenames = NULL;
    int i = 0;
    
    t_filenames = buildFileList();
    
    puts("\n");
    printf("t_filenames struct ptr from someOtherFunction(): %p\n",  t_filenames);
    printf("t_filenames->filename struct ptr from someOtherFunction(): %p\n",  t_filenames->filename);
    puts("\n");
    
    /* while (t_filenames->filename[i] != NULL) {
        printf("t_filenames->filename[%d] name (from someOtherFunction()): %s | ptr addr: %p \n",i, t_filenames->filename[i], t_filenames->filename[i]);
        ++i;
    } */ // works
    
    writeToFiles(t_filenames);
    
    return 0;
}
some_other_function.h
#include <stdio.h>
#include <linux/limits.h>
int someOtherFunction(void);
struct filepath *buildFileList(void);
void writeToFiles(struct filepath *t_filenames);
struct filepath {
    char *path[PATH_MAX];
    char *filename[FILENAME_MAX];
};
write_to_files.c
#include "write_to_files.h"
void writeToFiles(struct filepath *t_filenames) {
    
    FILE *curFile;
    int i = 0;  
    char msg[100] = "giggle, giggle, giggle....";  
    
    puts("\n");
    printf("t_filenames struct ptr from writeToFiles(): %p\n",  t_filenames);
    printf("t_filenames->filename struct ptr from writeToFiles(): %p\n",  t_filenames->filename);
    puts("\n");
    
    while (t_filenames->filename[i] != NULL) { 
        printf("filename name (from writeToFiles()): %s ptr addr: %p\n", t_filenames->filename[i], t_filenames->filename[i]);
        curFile = fopen(t_filenames->filename[i], "wb"); // works, but calling anymore functions were causing segfaults
        if (curFile != NULL) {
            puts("fprintf(curFile, %s, msg);");
            printf("current filename name: %s\n", t_filenames->filename[i]);
            // print childish message to file :-P
            fprintf(curFile, "%s", msg);
            puts("fclose(curFile);"); 
            fclose(curFile);
        } else {
            puts("loop broken!\n"); // always gets here way too early
            break;
        }         
        ++i;        
    }
    
    return;
}
write_to_files.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // needed for exit() call -- remove?
#include <linux/limits.h>
struct filepath {
    char *path[PATH_MAX];
    char *filename[FILENAME_MAX];
};
Thanks for any help with this!
 
     
    