Search code examples
cmemoryallocation

calloc vs memset one shows resulzs and one doesn't


So I am trying to get deep into C, and the following is a code that tackles memory allocations, files and strings/pointers. I have tried this both using callocate and memset. callocate seems to work fine but memset isn't. The idea of the code is as follows: I create some files, everytime a file is created its name is pushed to a list. I have a fixed number of files to keep. and after that number is exausted the oldest file is deleted everytime a new one is created. when using calloc. the prints show the correct messages and my folder has the last number of files: This is the code:

#include <stdio.h>
#include <stdlib.h>   // needed for malloc
#include <string.h>   // needed for strcpy
#include <unistd.h>

#define  Extension                         ".txt"
#define LOG_MIN_FILENAME_SIZE               32
#define  NBR_OF_FILES                        6

char buffer[LOG_MIN_FILENAME_SIZE];   
                                     
int timez = 0;
int minutes = 0;
int NUM_OF_EXISTING_FILES=0;


FILE *pf = NULL;
char* ListOfFiles[NBR_OF_FILES];
int status;



int main(void){
    
 for(int i=0; i<NBR_OF_FILES;i++){

ListOfFiles[i] = calloc(LOG_MIN_FILENAME_SIZE + 1, 1);




  for(int i=0; i<10;i++) { 
  
  
    pf =fopen(buffer, "w");
    sprintf(buffer, "%d""%d"Extension, minutes, timez);
    
    if(access(buffer, F_OK)==-1){
        
        NUM_OF_EXISTING_FILES++;
        fclose(pf); //closing the files is necessary
        if(NUM_OF_EXISTING_FILES >= NBR_OF_FILES){
                status = remove(ListOfFiles[0]);
                printf("removed");  
                }
        
        
        for(int i=0; i < NBR_OF_FILES-1; i++){
                strcpy(ListOfFiles[i], ListOfFiles[i+1]);// u cant use just normal assignment because it copies the head ot the pointer rather than the actual content of it
        }
    
        strcpy(ListOfFiles[NBR_OF_FILES-1], buffer);
    }
        
    timez++;
    minutes++;
    
    }
    
    for(int i=0; i<NBR_OF_FILES-1; i++){
        printf("%s", ListOfFiles[i]);
    }
}

now the code above works as I said but once I replace the calloc line with this :

    (void) memset(ListOfFiles[i], 0 ,LOG_MIN_FILENAME_SIZE + 2);
 }

the code doesn't show anything and no files are created. What is the difference between memset and calloc and why isnt it working here for me?


Solution

  • This is problematic:

    char* ListOfFiles[NBR_OF_FILES];
    memset(ListOfFiles[0], ...);
    

    memset expects its first argument to be a pointer to a buffer it'll modify. But ListOfFiles[0] is NULL[1]. Nothing good can come of that. Specifically, it's undefined behaviour that results in a SIGSEGV (crash) on modern general-purpose computers.

    calloc, on the other hand, allocates a buffer and returns a pointer to it. This is indeed the correct approach.


    1. Because ListOfFiles is found in static storage because it's a global. In other circumstances, it could be uninitialized, which is even worse.