Когда я запускаю свою программу с аргументами ./a.out и именем каталога в качестве аргументов, я получаю ошибку сегментации после того, как впервые печатаю «сделал это» на терминале и когда я пытаюсь прочитать из каталога (я знаюэто потому, что второй "сделал это" никогда не печатается).Я предполагаю, что это проблема с указателем, но не знаю, почему.Некоторые из проблем были исправлены благодаря совету комментаторов ниже.Я обновил этот пост с тех пор.
Почему я получаю это?Я пытался решить проблему с помощью valgrind, но я совершенно новичок в этом, и сообщения, которые он мне дал, не имели для меня смысла.Вот, пожалуй, самые полезные фрагменты из запущенного valgrind и из моего кода ниже:
==26237== Invalid read of size 1
==26237== at 0x4F1B940: invalid_name (opendir.c:91)
==26237== by 0x4F1B940: opendir (opendir.c:172)
==26237== by 0x108DF2: main (DirectorySearch.c:63)
==26237== Address 0x522d2c0 is 0 bytes inside a block of size 250 free'd
==26237== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108D7A: main (DirectorySearch.c:52)
==26237== Block was alloc'd at
==26237== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108C8B: main (DirectorySearch.c:36)
==26237==
==26237== Syscall param openat(filename) points to unaddressable byte(s)
==26237== at 0x4F4BDB1: __open_nocancel (open64.c:69)
==26237== by 0x4F1B952: opendir (opendir.c:190)
==26237== by 0x108DF2: main (DirectorySearch.c:63)
==26237== Address 0x522d2c0 is 0 bytes inside a block of size 250 free'd
==26237== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108D7A: main (DirectorySearch.c:52)
==26237== Block was alloc'd at
==26237== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26237== by 0x108C8B: main (DirectorySearch.c:36)
/*
Lists directory contents recursively, breadth first.
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct {
char* name;
char* abs;
struct node* next;
struct node* prev;
} node;
node* append(node*, char*, char*);
int print_list(node*);
int main(int argc, char** argv) {
if(argc != 2){
printf("You must provide 2 arguments: <./filename> <directory>\n");
return 0;
}
DIR* dp;
struct dirent* dirp;
struct stat buff;
char* name = malloc(250 * sizeof(char));
char* abs = malloc(250 * sizeof(char));
char* tmp = malloc(250 * sizeof(char));
node* head = malloc(sizeof(node));
if((chdir(argv[1])) == -1) {
fprintf(stderr, "%s\n", strerror(errno));
exit(errno);
}
head->name = argv[1];
head->abs = getcwd(tmp, 250);
head->next = NULL;
printf("%s\n", tmp);
free(name);
free(abs);
free(tmp);
int firstDir = 0;
do {
if(firstDir > 0) {
if (chdir(head->abs) == -1) {
fprintf(stderr, "%s\n", strerror(errno));
exit(errno);
}
}
dp = opendir(head->abs);
printf("%s\n", "made it");
while((dirp = readdir(dp)) != NULL)
{
printf("%s\n", "made it");
lstat(dirp->d_name, &buff);
if(S_ISREG(buff.st_mode))
printf("regular file: %s\n", dirp->d_name);
else if(S_ISDIR(buff.st_mode) && !S_ISLNK(buff.st_mode)) {
if (((strcmp(dirp->d_name, "..")) != 0) && ((strcmp(dirp->d_name, ".")) != 0)) {
printf("directory: %s\n", dirp->d_name);
name = calloc(250, sizeof(char));
abs = calloc(250, sizeof(char));
tmp = calloc(250, sizeof(char));
strncpy(name, dirp->d_name, strlen(dirp->d_name));
abs = getcwd(tmp, 250);
tmp = abs;
asprintf(&abs, "%s/%s", tmp, dirp->d_name);
head = append(head, name, abs);
free(name);
free(tmp);
}else
printf("directory: %s\n", dirp->d_name);
}
else if (S_ISLNK(buff.st_mode))
printf("%s %s\n", "LINK: ", dirp->d_name);
else if (S_ISFIFO(buff.st_mode))
printf("%s %s\n", "FIFO: ", dirp->d_name);
else if (S_ISCHR(buff.st_mode))
printf("%s %s\n", "CHAR DEV: ", dirp->d_name);
else if (S_ISBLK(buff.st_mode))
printf("%s %s\n", "BLOCK DEV: ", dirp->d_name);
else if (S_ISSOCK(buff.st_mode))
printf("%s %s\n", "SOCKET: ", dirp->d_name);
else
printf("%s\n", "Unknown file type.");
}
head = head->next;
if (head != NULL) {free(head->prev);}
printf("\n");
firstDir++;
} while (head != NULL);
free(abs);
return 0;
}
node* append(node* head, char *name, char *abs)
{
node* new = malloc(sizeof(node));
node* cursor = head;
while(cursor->next != NULL)
cursor = cursor->next;
node* prev = cursor;
new->name = name;
new->abs = abs;
new->next = NULL;
new->prev = prev;
cursor->next = new;
return head;
}