Элементы, переопределенные в списке из потока клавиатуры

#c #multithreading #linked-list

#c #многопоточность #связанный список

Вопрос:

[1] У меня проблема с моим потоком ввода с клавиатуры. В настоящее время я использую fgets для чтения ввода с клавиатуры, а затем сохраняю его в списке, используя List_add . Проблема в том, что моя программа, похоже, просто печатает последний введенный мной символ вместо разных строк сообщений.

ОБНОВЛЕНИЕ: код в потоке ввода клавиатуры

 #define MAX_LEN 258

static pthread_t keyboardThread;
static pthread_mutex_t *psharedMutex;
static List* pList;

void* inputFunction(void* unused){
    printf("Enter message:n");
    while (1) {         
        char* messageAllocated;
        messageAllocated = malloc(MAX_LEN);

        if(messageAllocated != NULL) {
            //Wait for user input
            fgets(messageAllocated, MAX_LEN, stdin);      // This is how C read something from keyboard

            pthread_mutex_lock(psharedMutex);
            {
                List_add(pList, messageAllocated);                // Add message to list for FCFS
            }
            pthread_mutex_unlock(psharedMutex);

            if (messageAllocated[0] == '!' amp;amp; messageAllocated[2] == '') {
                break;
            }
            
            memset(messageAllocated, 0, MAX_LEN);
        }
        else {
            printf("Malloc Failed.n");
        }
            
     };

    return NULL;
}

void KeyboardInput_init(List* myList, pthread_mutex_t *sharedMutex) {
    psharedMutex = sharedMutex;
    pList = myList;
    pthread_create(amp;keyboardThread, NULL, inputFunction, NULL);

}

void KeyboardInput_shutdown() {

    pthread_join(keyboardThread, NULL);
}
  

Код в main.c

 int main(int argc, char** args) {
    // Create 2 Lists for transmit and receive
    //List listPool;
    List* outboundList;                         // Used in keyboard and UDP sendto threads
    List* inboundList;                          // Used in screen and UDP recvfrom threads

    outboundList = List_create();
    inboundList = List_create();


    // Receive information for s-talk transmission (ports, machine names)
    setUpSTalkApplication();

    Printer_init();
    Signaller_init();
    Printer_waitForShutdown();
    Signaller_shutdown();

    // Startup Modules
    Receiver_init("Message received on Port ", amp;sharedMutex, remoteMachineName, hostPort);            // goes before keyboard
    KeyboardInput_init(outboundList, amp;sharedMutex);
    Sender_init(outboundList, amp;sharedMutex, amp;condVar, remoteMachineName, targetPort);
    //ScreenOutput_init(inboundList, amp;condVar, amp;sharedMutex);


    // Shutdown Modules
    //ScreenOutput_shutdown();
    KeyboardInput_shutdown();
    Receiver_shutdown();
    Sender_shutdown();


    printf("Done.n");
    while(List_count(outboundList) != 0) {
        char* x = List_trim(outboundList);
        printf("%s", x);
    };
    

    return 0;
}
  

Комментарии:

1. sizeof(messageAllocated) указывает размер указателя, а не размер буфера, на который он указывает. Используйте MAX_LEN вместо этого.

Ответ №1:

Во-первых, вы должны проверить указатель messageAllocated после malloc и sizeof(messageAllocated) только 4 или 8 байты, которые вы должны использовать MAX_LEN вместо sizeof(messageAllocated)

 while (1) {
    char * messageAllocated;
    messageAllocated = malloc(MAX_LEN);
    if(messageAllocated != NULL)
    {
        fgets(messageAllocated, MAX_LEN, stdin);
        List_add(pList, messageAllocated)
        if (messageAllocated[0] == '!') {
            break;
        }
      //hope you are doing this before reading another string, or else there will be memory leak
       free(messageAllocated); messageAllocated = NULL;
    }
    else
    {
        printf("malloc failedn");     
    }
}
  

Комментарии:

1. Обратите внимание, sizeof(messageAllocated) это не 1 байт. Это размер указателя. Обычно это 4 или 8 байт.

2. Итак, я изменил свой код, и его можно сохранить в списке, но когда я пытаюсь распечатать содержимое, символы случайным образом перемешиваются. я отредактировал свой исходный пост, чтобы вы могли увидеть мою реализацию. Как ни странно, включение free просто заставляет мою программу печатать все «! » опять же, поэтому я использую memset для этого

3. опять sizeof(MAX_LEN) неправильно, просто используйте fgets(messageAllocated, MAX_LEN, stdin); и memset(messageAllocated, 0, MAX_LEN); , и я не вижу free в вашем коде, лучше опубликовать полный рабочий код, на него будет легче ответить

4. Итак, я обновил ответ выше. Я пытаюсь также использовать мьютексы для потоков. Большое вам спасибо за вашу помощь!