C - проблема с добавлением строки в массив - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь добавить строку к следующему индексу моего массива, однако у меня возникает странная проблема, когда я добавляю любой индекс, отличный от 1 (да, я индексирую свой массив из одного, просто для простоты, чтобы соответствовать фактическому номеру пункта, я извиняюсь!). По сути, если я вернусь к индексу 1, все в порядке, однако, когда я добавляю к индексу 2, значение индекса 1, похоже, меняется на значение, которое я планирую поместить в индекс 2, даже до строк кода, где я добавьте значение к индексу 2. Например:

Скажем, я пытаюсь добавить 'test1' в мой массив queuedHashed [100] [101] с индексом 1, и я провожу печать всех элементов массива, рядом с номером индекса я получаю:

1: test1

Однако, когда я go добавляю 'test2' с индексом 2 к массиву, я получаю:

1: test2
2: test2

I ' Я часами выдергивал свои волосы, пытаясь это исправить, и не вижу, где я ошибаюсь. В настоящее время я передаю свои переменные, используя структуры (из-за ограничений GTK), однако эта проблема также сохранялась, когда переменные были глобальными переменными, прежде чем я сменил их на локальные.

Вот мой код:

queue_ha sh функция:

static void queue_hash (GtkButton *button, gpointer user_data) {

    struct data *dataStruct = user_data;

    GtkWidget *hashWid = dataStruct->hash;
    GtkWidget *hashTypeWid = dataStruct->hashType;
    GtkWidget *hashEntryLabel = dataStruct->hashEntryLabel;
    GtkListStore *store;
    GtkTreeIter iter;

    const char* hash = gtk_entry_get_text(GTK_ENTRY(hashWid));
    int hashLen = gtk_entry_get_text_length(GTK_ENTRY(hashWid));
    int hashTypeIndex = gtk_combo_box_get_active(GTK_COMBO_BOX(hashTypeWid));

    store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));

    // TODO: Update max length to 128

    if (hashLen > 100) {
        gtk_widget_set_name(hashWid, "fieldsError");
        gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash exceeds max length of 100");
        g_print("Hash length exceeds 100: Exiting.");

        return;
    }

    gtk_widget_set_name(hashWid, "");
    gtk_widget_set_name(hashTypeWid, "");
    gtk_widget_set_name(hashEntryLabel, "");
    gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash to be cracked:");

    if ((strcmp(hash, "") == 0) || (hashTypeIndex == -1)) {

        if (strcmp(hash, "") == 0) {
            gtk_widget_set_name(hashWid, "fieldsError");
        }

        if (hashTypeIndex == -1) {
            gtk_widget_set_name(hashTypeWid, "fieldsError");
        }

        g_print("Invalid Entry \n");

    } else {

        // Check for spaces in hash - return if found
        // TODO: Check for other non-alphabetical chars/symbols

        for (int i = 0; i < hashLen; i++) {
            if (hash[i] == ' ') {
                gtk_widget_set_name(hashWid, "fieldsError");
                gtk_widget_set_name(hashEntryLabel, "errorLabel");
                gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Please remove all spaces");
                g_print("Space found in hash: Exiting\n");
                return;
            }
        }

        g_print("//////////////////////////////\n");
        g_print("Before: (HashCount: %i)\n", dataStruct->hashCount);
        //test_queue(dataStruct->queuedHashes, dataStruct->hashCount);

        for (int i = 1; i <= dataStruct->hashCount; i++) {
            g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
        }

        sleep(1);

        // Save hash to array
        ++dataStruct->hashCount;
        g_print("After Increment: %i\n", dataStruct->hashCount);
        g_print("Hash: %s\n", hash);
        dataStruct->queuedHashes[dataStruct->hashCount][0] = hash;  // Line to actually add new string to array
        dataStruct->queuedHashTypes[dataStruct->hashCount] = hashTypeIndex;

        g_print ("Queue Hash: %s    %i\n", dataStruct->queuedHashes[dataStruct->hashCount][0], dataStruct->queuedHashTypes[dataStruct->hashCount]);

        sleep(1);

        g_print("After: (HashCount: %i)\n", dataStruct->hashCount);
        //test_queue(dataStruct->queuedHashes, dataStruct->hashCount);

        g_print("Manual 1: %s, 2: %s\n", dataStruct->queuedHashes[1][0], dataStruct->queuedHashes[2][0]);

        for (int i = 1; i <= dataStruct->hashCount; i++) {
            g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
        }
}

Часть вызывающей функции, которая вызывает вышеуказанную функцию:

    struct data *hash_data = g_new0(struct data, 1);
    hash_data->hash = hashEntry;
    hash_data->hashType = hashSelect;
    hash_data->hashEntryLabel = hashEntryLabel;
    g_signal_connect(queueButton, "clicked", G_CALLBACK (queue_hash), hash_data);

Определение глобальной структуры:

struct data {
    char* queuedHashes[100][101];
    int queuedHashTypes[100];
    int hashCount;
    GtkWidget *hash;
    GtkWidget *hashType;
    GtkWidget *hashEntryLabel;
    GtkTreeSelection *selectedHash;
};

У меня есть много операторов печати, чтобы проиллюстрировать, где вещи, кажется, неожиданно меняются, вот вывод программы при запуске, и введены два значения:

//////////////////////////////
Before: (HashCount: 0)
After Increment: 1
Hash: 12357890
Queue Hash: 12357890    1
After: (HashCount: 1)
Manual 1: 12357890, 2: (null)
1: 12357890
//////////////////////////////
Before: (HashCount: 1)
1: asdfghjkl    <----- This should be "1: 12357890", as the array has not yet been changed
After Increment: 2
Hash: asdfghjkl      
Queue Hash: asdfghjkl    2
After: (HashCount: 2)
Manual 1: asdfghjkl, 2: asdfghjkl
1: asdfghjkl      <----- This should be "1: 12357890"
2: asdfghjkl

Вот мой полный код для всех соответствующих функций: https://pastebin.com/41W3n5W2

Любая помощь будет принята с благодарностью, спасибо!

1 Ответ

1 голос
/ 09 апреля 2020

Симптом, описанный в вопросе, обычно указывает на то, что код не создает копию строки. В результате каждая «строка», хранящаяся в массиве, является просто указателем на один и тот же входной буфер, и поэтому каждая запись в массиве представляется последней строкой, полученной от пользователя.

Исправление заключается в сделать копию строки. В системе POSIX вы можете использовать функцию strdup для копирования. Функция strdup - это, по сути, вызов malloc, за которым следует вызов strcpy, который создает копию строки и возвращает указатель на копию. Поэтому, если ваша реализация не поддерживает strdup, вы можете легко написать свою собственную функцию для выделения памяти и скопировать строку.

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