Попытка отобразить карту выделенной памяти в смоделированном диспетчере памяти ОС

Несколько клиентов отправляют имя своего задания и запрос памяти на сервер. Сервер действует как диспетчер памяти и распределяет память для максимально возможного количества клиентов, используя подкачку в качестве схемы выделения памяти. Я использую FIFO для связи клиент-сервер.

Проблема, с которой я сталкиваюсь, заключается в том, что после обработки всех клиентов я хотел бы отобразить карту выделенной памяти на стороне сервера. Другими словами, я хотел бы показать, какие кадры были выделены какому клиенту.

Ниже приведена часть моего серверного приложения. Я также приложил некоторый вывод, который может помочь понять проблему. Все работает, как и ожидалось, до конца программы (где она распечатывает кадры, назначенные каждому клиенту; последний цикл for на server.c). Массив clientAllocation — это массив, который содержит личное имя FIFO каждого клиента. Я пытался присвоить индекс выделенного фрейма (в массиве выделенных кадров) в качестве частного FIFOName клиента. Я не уверен, почему это не работает. Спасибо заранее за любую помощь.

Любой ответ должен быть переносимым. Я должен иметь возможность запускать этот код на машине UNIX с помощью компилятора cygwin-gcc. Я тестирую код на Windows, потому что это моя основная машина. Я подключаюсь к UNIX-машине в своем университете с помощью PuTTY после каждой пары изменений кода и проверяю, работает ли код и там.

server.c

...//include statements

#define FRAMESIZE 256
#define MAX_LENGTH_FIFO_NAME 16
#define MAX_LENGTH_JOB_NAME 32
#define MAX_LENGTH_MESSAGE 256

int main(void)
{
    int numOfClients = 0; //total number of clients this server will process
    int totalNumOfFrames = 0; //total number of frames in memory
    int frames = 0; //copy of numOfFrames used to allocate frames for client

    //Struct to recieve from client
    struct
    {
        char jobName[MAX_LENGTH_JOB_NAME];
        char privateFIFOName[MAX_LENGTH_FIFO_NAME];
        int memoryRequest;
    }input;

    //Struct to send to client containing the calculated frames and the fragmentation
    struct
    {
        char message[MAX_LENGTH_MESSAGE];
        int fragmentation;
        int totalNumOfFrames;
        int frameNumbers[totalNumOfFrames];
    }output;

    ... //getting input from user and doing error checking

    int allocatedFrames[totalNumOfFrames]; //an array of "flags" that will keep track whether a frame is allocated or not
    char* clientsAllocation[totalNumOfFrames]; //an array to keep track of what frames are allocated to what client

    memset(allocatedFrames, 0, sizeof(allocatedFrames)); //make sure all values in the array are set to 0 to prevent random values
    memset(clientsAllocation, 0, sizeof(clientsAllocation));

    int i = 0;
    int j = 0;

    for (i; i < numOfClients; i++)
    {
        if (input.memoryRequest >= FRAMESIZE && input.memoryRequest <= memoryLeft)
        {
            ...
            frames = 0;

            if (framesLeft >= numOfFrames)
            {
                j = 0;
                while (frames < numOfFrames)
                {
                    for (j; j < totalNumOfFrames; j++)
                    {
                        if (allocatedFrames[j] == 0) //if the value at j is 0, then this is an empty frame and can be allocated
                        {
                            allocatedFrames[j] = 1; //switch the value to 1 in both arrays
                            output.frameNumbers[j] = 1;
                            clientsAllocation[j] = input.privateFIFOName; //keep track of what frames this client was allocated
                            printf("%d: %s\n", j, clientsAllocation[j]);
                            printf("SERVER:> Frame Allocated: %d\n", j);
                            break; //breaks out of this 'for' loop which should only be run as many times as there are frames to be allocated
                        }
                    }
                    frames++; //increment the temporary frames variable to keep track of how many times to run the for loop
                }

                ... //calculations on framesLeft and memoryLeft
            }
            //if it is not a valid request, (i.e. requesting more frames than are available)
            else
            {
                ... //some error printing
            }
        }
        else if (...)... //range checking but the code is very similar to above
    }

    i = 0;
    for (i; i < totalNumOfFrames; i++)
    {
        printf("%d: %s\n", i, clientsAllocation[i]);
    }
    printf("\n\n");

    return 0;
}

Вывод


person Ethan    schedule 29.10.2017    source источник
comment
Это много в основном нерелевантного кода. Прочтите страницы справки, особенно разделы с именами На какие темы я могу задать здесь? и Каких типов вопросов мне следует избегать?. Также, пожалуйста, пройдите экскурсию и прочитайте о как задавать хорошие вопросы. Наконец, узнайте, как создать минимальный, полный и проверяемый пример.   -  person Some programmer dude    schedule 29.10.2017
comment
@Ethan, для программистов, которые пишут функции длиной более 20 строк, существует особый ад. Вы, кажется, в нем.   -  person jwdonahue    schedule 29.10.2017
comment
@Someprogrammerdude, спасибо за советы. Я отредактировал свой вопрос и удалил много ненужного кода. Надеюсь, стало легче понять, в чем моя проблема.   -  person Ethan    schedule 29.10.2017
comment
@jwdonahue, длина функции полностью основана на мнении. Я понимаю, что main — это функция, и мой main довольно длинный. Тем не менее, я только начинаю изучать C и учусь, проходя курс по операционным системам. Так что буду признателен за полезную критику. Говорить, что я принадлежу программистскому аду, совершенно бесполезно.   -  person Ethan    schedule 29.10.2017
comment
@Ethan, статистика показывает, что большинство программных ошибок появляются в функциях длиннее 10 строк. Многие компании имеют мягкие/жесткие ограничения на длину функции из-за извлеченных дорогостоящих уроков. Имейте это в виду, когда в следующий раз вам не удастся найти собственные ошибки в слишком длинных функциях.   -  person jwdonahue    schedule 29.10.2017


Ответы (1)


Вы всегда назначаете один и тот же адрес буфера используемой в данный момент записи массива имен клиентов.

clientsAllocation[j] = input.privateFIFOName;

Вы делаете это, задавая имя/идентификатор массива char во входной структуре.
Он обрабатывается как указатель на char и назначается всем используемым записям внутри clientsAllocation.

Итак, в конце, при печати, все указатели ссылаются на один и тот же массив char
, и вы получаете список одинаковых имен, последний записанный в буфер.

Чтобы избежать этого, вы можете malloc() немного памяти для каждого имени и заполнить его текущим именем путем копирования строки.

Конечно, вы должны в какой-то момент освободить эти выделенные памяти.
Для простой демонстрационной программы освобождение после печати кажется подходящим.

person Yunnosch    schedule 29.10.2017
comment
Спасибо за ответ. Я понял, что происходит, после того как прочитал главу об указателях и манипулировании строками в своем учебнике C. Я ценю помощь и указание меня в правильном направлении! :) - person Ethan; 30.10.2017