C - 无法将字符串添加到数组

C - Trouble adding string to array

我正在尝试将字符串添加到我的数组的下一个索引,但是我遇到了这个奇怪的问题,当我添加到 1 以外的任何索引时(是的,我从一个索引我的数组,为了简单起见,只是为了匹配项目的实际数量,对不起!)。本质上,如果我 ass 到索引 1,一切都很好,但是当我添加到索引 2 时,索引 1 的值似乎更改为我计划放入索引 2 的值,甚至在我所在的代码行之前将值添加到索引 2。例如:

假设我尝试将 'test1' 添加到我的数组 queuedHashed[100][101] 的索引 1,然后我 运行 打印数组的所有元素,在索引号旁边,我得到:

1: test1

然而,当我将索引 2 处的 'test2' 添加到数组时,我会得到:

1: test2
2: test2

为了解决这个问题,我费了好几个小时,但看不出哪里出了问题。我目前正在使用结构传递我的变量(由于 GTK 的限制),但是当变量是全局变量时,在我将它们更改为本地变量之前,这个问题仍然存在。

这是我的代码:

queue_hash函数:

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

非常感谢任何帮助,谢谢!

问题中描述的症状通常表明代码没有复制字符串。结果,存储在数组中的每个 "string" 只是指向同一个输入缓冲区的指针,因此数组中的每个条目似乎都是从用户收到的最后一个字符串。

修复方法是复制字符串。在 POSIX 系统上,您可以使用 strdup 函数进行复制。 strdup 函数本质上是对 malloc 的调用,然后是对 strcpy 的调用,后者生成字符串的副本,而 returns 是指向副本的指针。因此,如果您的实现不支持 strdup,您可以轻松编写自己的函数来分配内存,并复制字符串。