#c #pointers #struct
#c #указатели #структура
Вопрос:
Я работаю над программой на C для обхода файловой системы в Linux, записи памяти каждого файла и вывода гистограммы в конце. У меня возникли проблемы с передачей указателя на структуры, и я не слишком знаком с тем, как они передаются в C.
Я пытаюсь передать свой указатель head в мою функцию readDirectory, но то, как он ведет себя, передает пустой заголовок связанного списка при каждом вызове функции. Внутри функции она добавляет узлы, как и ожидалось, но каждый раз, когда она вызывает себя рекурсивно, кажется, что список уничтожен, а заголовок снова становится нулевым.Я предполагаю, что я передаю их неправильно, поэтому может кто-нибудь, пожалуйста, подсказать мне правильный способ их передачи или указать мне на хороший ресурс, который хорошо это объясняет?
Проблема также возникает, когда я передаю ее в функцию printHistrogram, но если я смогу исправить это в другом месте, я буду знать, как исправить это и здесь.
Заранее спасибо. -Крис
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
struct memList
{
int mem;
struct memList* next;
};
void readDirectory(const char*, struct memList*);
void printHistogram(struct memList*, int binSize);
int main(int argc, char* argv[])
{
struct memList* head = NULL;
if (argc != 3)
{
perror("Not enough parametersn");
}
int binSize = strtol(argv[2], NULL, 10);
readDirectory(argv[1], head);
printHistogram(head, binSize);
return 0;
}
void readDirectory(const char * passedDir, struct memList* head)
{
DIR * directory = opendir(passedDir);
if (directory == NULL)
printf("Unable to open directoryn");
while(1)
{
struct dirent * current;
current = readdir(directory);
if (!current)
break;
if ((current->d_type == 4) amp;amp; (strcmp(current->d_name, ".") != 0) amp;amp; (strcmp(current->d_name, "..") != 0)) //current path is directory but not the current or parent
{
char * path = malloc(sizeof(char) * 300);
strcpy(path, passedDir);
if (path[strlen(path) - 1] != '/')
strcat(path, "/");
strcat(path, current->d_name);
readDirectory(path, head);
free(path);
}
else
{
char * path = malloc(sizeof(char) * 300);
strcpy(path, passedDir);
if (path[strlen(path) - 1] != '/')
strcat(path, "/");
strcat(path, current->d_name);
struct stat tempStat;
stat(path, amp;tempStat);
free(path);
int temp = tempStat.st_size;
if (head == NULL)
{
head = (struct memList*)malloc(sizeof(struct memList));
head->next = NULL;
head->mem = temp;
}
else
{
struct memList * tempStruct = (struct memList*)malloc(sizeof(struct memList));
tempStruct->next = head;
tempStruct->mem = temp;
head = tempStruct;
//printf("mem is %dn", head->mem); //debugging
}
}
}
closedir(directory);
}
void printHistogram(struct memList* head, int binSize)
{
int numElements = 10;
int * array = (int*)malloc(sizeof(int) * numElements);
for (int i = 0; i < numElements; i )
array[i] = 0;
while(head != NULL)
{
//printf("mem is %dn", head->mem); //debugging
int temp = head->mem;
int temp2 = ((temp - (temp % binSize)) / binSize);
if ((temp2 1) > numElements)
{
int * new = realloc(array, (sizeof(int) * (temp2 1)));
array = new;
for (int i = numElements; i < (temp2 1); i )
array[i] = 0;
numElements = (temp2 1);
}
array[temp2] = 1;
head = head->next;
}
for (int i = 0; i < numElements; i )
{
printf("%dn", array[i]);
printf("Block %d: ", i 1);
for (int j = 0; j < array[i]; j )
printf("*");
printf("n");
}
}
Комментарии:
1.
readDirectory(argv[1], head);
head передается по значению.2. Не имеет отношения к рассматриваемой проблеме, но вы можете захотеть использовать
nftw
вместо того, что вы делаете прямо сейчас.
Ответ №1:
Изучите «передача по ссылке» и «передача по значению». C передается по значению.
Если вы хотите, head
чтобы его модифицировали таким образом, чтобы оно сохраняло свое значение снаружи readDirectory
, тогда вам нужно передать указатель на указатель.
Комментарии:
1. Спасибо за помощь, ребята. Я изменил параметры заголовка функции с * на **, изменил переданные параметры с head на amp;head , и мой метод вызывает из head-> в (*head)-> После пары настроек моих формул программа, наконец, отлично работает. Я уверен, что это можно оптимизировать больше, как упомянутый выше nftw, но для начала я доволен этим.