Ошибка Segfault / несовместимого типа при попытке создать массив структур каталогов - PullRequest
0 голосов
/ 05 декабря 2018

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

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char **argv) 
{
    DIR *d = NULL;
    struct dirent *dir = NULL;
    struct dirent *d_array[50]; //big overkill array to avoid realloc
    size_t n = 0; //number of items

    d = opendir("scandir"); //name of directory to search
    if(d)
    { 
        while((dir = readdir(d))!=NULL) {
            //d_array[n] = malloc(sizeof(struct dirent));
            d_array[n++] = dir;
        }
        closedir(d);
    }
    for(size_t i = 0;i<n;i++) {
        printf(d_array[n]->d_name);
        free(d_array[n]);
    }
    free(d_array);
    return 0;
}

Запуск приведенного выше кода приводит кОшибка сегментации: 11. Я думал, что это, вероятно, потому, что я правильно распределил память для структур (как видно из закомментированного malloc), но в том числе это дает следующую ошибку:

error: assigning to 'struct dirent *' from incompatible type
  'void *'

ДонНе понимаю, почему d_array[n] = malloc(sizeof(struct dirent)), дословно из нескольких сообщений на эту тему, имеет эту несовместимую ошибку типа.И если это неуместно использовать, почему я получаю segfault?

1 Ответ

0 голосов
/ 05 декабря 2018

Запуск приведенного выше кода приводит к ошибке сегментации: 11.

Это может быть из-за

    printf(d_array[n]->d_name);

или

    free(d_array[n]);

, поскольку n - это число записей каталога, а d_array[n] неинициализировано.(Похоже, вы имели в виду d_array[i]) Также обратите внимание, что вы не должны пытаться освободить указатель, возвращенный readdir(), так как он вам не принадлежит.В документации конкретно сказано, что вы не должны пытаться освободить ее.Это потенциально применимо к версии, в которой вы просто назначаете указатель самому массиву.

Это также может быть связано с

free(d_array);

, поскольку d_array сам по себе не выделяется динамически,Вы можете разумно надеяться, что ваш компилятор предупредит об этом.У меня есть.

Я не понимаю, почему d_array[n] = malloc(sizeof(struct dirent)), дословно из нескольких сообщений на эту тему, имеет эту несовместимую ошибку типа.

Это было быпотому что ваш компилятор не соответствует.Возможно, вы используете компилятор C ++ вместо компилятора C - они не являются взаимозаменяемыми.Это утверждение является абсолютно допустимым C, учитывая объявления, которые находятся в области видимости, где оно появляется в вашем коде.

Приложение: Что касается того, что вы действительно должны делать, если вы собираетесь динамически распределятьпамяти для элементов d_array, на которые нужно указать (и вам следует, если вы вообще используете массив указателей), вам нужно скопировать структуры Point-to-10 * struct dirent в выделенное пространство, а не назначатьвозвращенные указатели прямо на массив.Это было бы

    *d_array[i] = *dir;

, как Пол Огилви впервые указал в уже удаленном ответе.

...