Передача указателя на структуру в C? - PullRequest
0 голосов
/ 18 марта 2019

Я работаю над программой на C, чтобы обойти файловую систему в Linux, записать память каждого файла и выложить гистограмму в конце. У меня проблемы с передачей указателя на структуры, и я не слишком знаком с тем, как они передаются в C.

Я пытаюсь передать мой указатель на голову в мою функцию readDirectory, но то, как он ведет себя, передает его в пустой заголовок связанного списка при каждом вызове функции. Внутри функции он добавляет к узлам, как и ожидалось, но каждый раз, когда он вызывает себя рекурсивно, кажется, что список стирается, и голова возвращается к NULL. Я предполагаю, что я передаю их неправильно, так что может кто-то сказать мне, пожалуйста, правильный способ передать их или указать мне хороший ресурс, который это хорошо объясняет?

Эта проблема также возникает, когда я передаю ее в функцию 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 parameters\n");
    }

    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 directory\n");

    while(1)
    {
        struct dirent * current;

        current = readdir(directory);
        if (!current)
            break;

        if ((current->d_type == 4) && (strcmp(current->d_name, ".") != 0) && (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, &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 %d\n", 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 %d\n", 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("%d\n", array[i]);
        printf("Block %d:  ", i + 1);
        for (int j = 0; j < array[i]; j++)
            printf("*");
        printf("\n");
    }
}

1 Ответ

0 голосов
/ 18 марта 2019

Изучите «передать по ссылке» и «передать по значению».C это передать по значению.

Если вы хотите, чтобы значение head было изменено таким образом, чтобы оно сохраняло свое значение вне readDirectory, вам нужно передать указатель на указатель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...