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?
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.
ListOfFiles
is found in static storage because it's a global. In other circumstances, it could be uninitialized, which is even worse.