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

Я пишу небольшую клиент-серверную C-программу.Функция клиента будет использоваться для запроса имен всех обычных файлов в каталоге на сервере.Сервер вернет имена файлов в виде массива char по TCP.Моя программа имеет много вариантов, которые можно запускать индивидуально в любое количество раз и легко переключаться между ними.Когда я пытаюсь запустить функцию, чтобы получить имена файлов, я получаю ошибку сегментации и не знаю почему.Я вставил свой код клиента и сервера ниже.

Сервер:

void dir_details(int socket) {
    //Set up appropriate variables
    char StringArray[1024];
    struct dirent *de;
    struct stat st = {0};

    //If the upload directory doesn't exist, create it
    if (stat("upload", &st) == -1) {
        mkdir("upload", 0777);
    }

    //Opening the upload directory to be read
    DIR *dr = opendir("upload");

    if (dr == NULL) {
        printf("Could not open directory.");
    }

    //Add each file name to a char array
    while ((de = readdir(dr)) != NULL) {
        strcat(StringArray, de->d_name);
        strcat(StringArray, "\n");
    }

    closedir(dr);
    size_t n = sizeof(StringArray);
    //Send the char array back to the client
    writen(socket, (unsigned char *) &n, sizeof(size_t));   
    writen(socket, (unsigned char *) StringArray, n);   
    strcpy(StringArray, "");
    free(de);
}

Клиент:

void dir_details(int socket) {
    //Set up char array to be received form the server
    char dirdetails[5000];
    size_t k;

    //Receive char array from the server
    readn(socket, (unsigned char *) &k, sizeof(size_t));    
    readn(socket, (unsigned char *) &dirdetails, k);

    //Print the array to the client
    printf("%s\n", dirdetails);
}

1 Ответ

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

Читать внимательно readdir (3) .На практике последний член struct dirent d_name может вести себя как гибкий элемент массива , даже если он не может быть точно задокументирован как таковой.

Вероятно, StringArrayпереполнение буфера (и вы не проверяете это достаточно внимательно).Вы забыли обнулить его (по крайней мере, memset(StringArray, 0, sizeof (StringArray)); ...)

Конечно, вы неправильно понимаете malloc .Он может потерпеть неудачу, и вам всегда нужно использовать его результат.Подробнее о C динамическом распределении памяти .

Читать Как отлаживать небольшие программы .Скомпилируйте все предупреждения и отладочную информацию, например, с gcc -Wall -Wextra -g, если используете GCC .

Потратьте несколько дней, читая больше о базовом программировании на Си.Прочитайте учебник C .Посмотрите на C ссылку сайт.В случае сомнений, проверьте стандарт C11 n1570 после прочтения хорошего учебника по программированию на C.Изучите исходный код небольших бесплатных программ программ для вдохновения.

После того, как вы улучшите свои базовые навыки программирования на C, прочитайте кое-что о программировании на Linux, например, ALP .

Уничтожьте вашу бессмысленную программу (она настолько глючит, что не стоит ее улучшать или пытаться ее утилизировать). Как только вы улучшили свой уровень программирования на C, снова начните писать свою программу с нуля. Используйте хорошую систему контроля версий (я рекомендую git ), и сделайте несколько очень итерационных и инкрементныхразработка (напишите одну или две дюжины строк, скомпилируйте их со всеми предупреждениями, улучшите их, чтобы не было предупреждений, проверьте их с помощью отладчика GDB , а затем передайте их в систему управления версиями и повторите все).Внимательно прочитайте документацию по каждой используемой функции (например, man страниц, таких как read (2) , syscalls (2) , errno (3) , printf (3) и т. Д.)

Примечание.Вам, вероятно, следует потратить хотя бы целую неделю на чтение, прежде чем касаться клавиатурыЯ действительно рекомендую прочитать SICP (отличное введение в программирование, которое не использует C, но учит очень важным и актуальным понятиям)

...