It is necessary to write an analogue ls -lR. The name of the directory is served as the first argument, and you need to recursively display the contents of the directory as (sorted):

It seems to have written, but I just can’t understand where RunTime Error can be. Help please, absolutely desperate. It seems to have made arrays without allocating memory, anyway, the same RunTime Error

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <sys/types.h> #include <sys/stat.h> #include <grp.h> #include <pwd.h> #include <unistd.h> int comp (const void *i, const void *j) { return strcmp(*(const char**)i, *(const char**)j); } void fill(char *array, struct stat fStat){ if(S_ISDIR(fStat.st_mode)) array[0] = 'd'; else if(S_ISBLK(fStat.st_mode)) array[0] = 'b'; else if(S_ISLNK(fStat.st_mode)) array[0] = 'l'; else if(S_ISCHR(fStat.st_mode)) array[0] = 'c'; else if(S_ISFIFO(fStat.st_mode)) array[0] = 'p'; if (fStat.st_mode & S_IRUSR) array[1] = 'r'; if (fStat.st_mode & S_IWUSR) array[2] = 'w'; if (fStat.st_mode & S_IXUSR) array[3] = 'x'; if (fStat.st_mode & S_IWGRP) array[4] = 'w'; if (fStat.st_mode & S_IRGRP) array[5] = 'r'; if (fStat.st_mode & S_IXGRP) array[6] = 'x'; if (fStat.st_mode & S_IROTH) array[7] = 'r'; if (fStat.st_mode & S_IWOTH) array[8] = 'w'; if(fStat.st_mode & S_IXOTH) array[9] = 'x'; } int countF(DIR *dir){ int count = 0; while((readdir(dir)) != NULL){ ++count; } rewinddir(dir); return count; } void recursion(char *directoryName){ struct stat f; if(lstat(directoryName, &f) != 0){ perror("Error"); exit(0); } if(!S_ISDIR(f.st_mode)){ struct passwd *p = getpwuid(f.st_uid); struct group *g = getgrgid(f.st_gid); char array [12]; int l = 0; for (l = 0; l < 9; ++l) { array[l] = '-'; } fill(array, f); printf("%s %d ", array, f.st_nlink); if (p != NULL && g != NULL) { printf("%s %s", p->pw_name, g->gr_name); } else if (p == NULL && g != NULL) { printf("%d %s", f.st_uid, g->gr_name); } else if (p != NULL && g == NULL) { printf("%s %d", p->pw_name, f.st_gid); } else { printf("%d %d", f.st_uid, f.st_gid); } printf("%lld %s", f.st_size, directoryName); if (S_ISLNK(f.st_mode)) { char link[1000000]; if (readlink(directoryName, link, 1000000) == -1) { exit(1); } else { printf(" -> %s", link); } } printf("\n"); } else { DIR *dir = opendir(directoryName); if (dir == NULL) { perror("Error"); closedir(dir); return; } int countOfFiles = countF(dir); if (directoryName[strlen(directoryName) - 1] != '/') { directoryName = (char *) realloc(directoryName, strlen(directoryName) + 2); strcat(directoryName, "/"); } char arrayOfFiles[countOfFiles][10000000]; char **arrayOfDirectories = malloc(1000000 * sizeof(char*)); int j, k; for (j = 0; j < countOfFiles; ++j) { if (arrayOfFiles[j] == NULL) { perror(""); free(arrayOfFiles[j]); exit(0); } for (k = 0; k < strlen(readdir(dir)->d_name); ++k) { arrayOfFiles[j][k] = readdir(dir)->d_name[k]; } } qsort(arrayOfFiles, countOfFiles, sizeof(char *), comp); int countOfDirectories = 0; for (k = 0; k < countOfFiles; ++k) { if (!(strlen(arrayOfFiles[k]) == 1 && arrayOfFiles[k][0] == '.') && !(strlen(arrayOfFiles[k]) == 2 && arrayOfFiles[k][0] == '.' && arrayOfFiles[k][1] == '.')) { struct stat Stat; if (lstat(directoryName, &Stat) != 0) { perror(""); exit(1); } if (S_ISDIR(Stat.st_mode)) { arrayOfDirectories[countOfDirectories] = directoryName; countOfDirectories++; } struct passwd *p = getpwuid(Stat.st_uid); struct group *g = getgrgid(Stat.st_gid); char array[12]; int l = 0; for (l = 0; l < 10; ++l) { array[l] = '-'; } fill(array, Stat); printf("%s %d ", array, f.st_nlink); if (p != NULL && g != NULL) { printf("%s %s", p->pw_name, g->gr_name); } else if (p == NULL && g != NULL) { printf("%d %s", f.st_uid, g->gr_name); } else if (p != NULL && g == NULL) { printf("%s %d", p->pw_name, f.st_gid); } else { printf("%d %d", f.st_uid, f.st_gid); } printf("%lld %s", Stat.st_size, arrayOfFiles[k]); if (S_ISLNK(Stat.st_mode)) { char link[1000000]; if (readlink(directoryName, link, 1000000) == -1) { exit(1); } else { printf(" -> %s", link); } } printf("\n"); } } printf("\n"); for (k = 0; k < countOfDirectories; ++k) { recursion(arrayOfDirectories[k]); } for (j = 0; j < countOfDirectories; ++k) { free(arrayOfDirectories); } free(directoryName); free(arrayOfDirectories); closedir(dir); } } int main(int argc, char **argv) { recursion(argv[1]); return 0; } 
  • So what exactly is a mistake? Runtime errors are many different. You give a complete message, but it turns out the question of the level "I have a knock under the floor." - freim

1 answer 1

  1. Recursive function contains local arrays inside

     char link[1000000]; 

    and even

     сhar arrayOfFiles[countOfFiles][10000000]; 

    This can easily crash due to stack overflow. Maybe you should temper your appetites?

  2. Check

     for (j = 0; j < countOfFiles; ++j) { if (arrayOfFiles[j] == NULL) 

    is meaningless. arrayOfFiles[j] cannot be NULL .

  3. free(arrayOfFiles[j]); - is it like this?

  4. Call

     qsort(arrayOfFiles, countOfFiles, sizeof(char *), comp); 

    for such arrayOfFiles is incorrect and meaningless.

  5.  directoryName = (char *) realloc(directoryName, strlen(directoryName) + 2); 

    and further

     free(directoryName); 

    But initially directoryName is argv[1] . Who allowed you to apply realloc or free to argv[1] ?

  6. arrayOfDirectories[countOfDirectories] = directoryName; ??? What is the meaning of the loop, which at each iteration puts the next arrayOfDirectories[countOfDirectories] to point to the same directoryName buffer? What is the point of doing if (lstat(directoryName, &Stat) != 0) { for the same directoryName at each iteration of the loop?

  7. What is this nonsense?

     for (j = 0; j < countOfDirectories; ++k) { free(arrayOfDirectories); } free(arrayOfDirectories);