0

在使用 Python 和 JS 等动态语言进行了大约 5 年的编程之后,我开始觉得我错过了幕后发生的事情。像这样的语言真的很棒,因为它们让你专注于你必须做的事情,利用指针、内存分配和许多搜索、排序、插入算法的麻烦。尽管我从不后悔使用这些语言,因为我真的觉得它们非常强大,但我觉得,为了成为一个更好的程序员,我需要退后一步,了解幕后发生的事情!

我决定通过编写一个简单的单词计数器来做到这一点:该应用程序获取所有参数并输出所有唯一单词,每个单词都有一个计数器:“Hello world Hello”将返回“Hello:2”,“world:1”(不考虑实际的输出结构)。这个程序是 Python 的等价物:

import sys
from collections import defaultdict

def main():
    results = defaultdict(int)
    for word in sys.argv[1:]:
        results[word] += 1
    print results

用 C 语言编写它有点不同,我觉得我对指针、指针数组和所有这些东西都搞错了!我想变得更好,帮助我变得更好!!

#include <stdio.h>
#include <stdlib.h>

// This is what a key-value pair: <int, string>
typedef struct {
    int counter;
    unsigned char* word;
} hashmap;

// Checks if inside the array of results, hashmap->word is equals to word paramter
hashmap* get_word_from_results(hashmap* results[], int count, const char* word) {
    int i;
    hashmap* result;
    for (i = 0; i < count; i++) {
        result = results[i];
        if (result->word == (unsigned char *)word)
            return result;
    }
    return NULL;
}

int main(int argc, const char *argv[])
{
    hashmap* results;
    int results_counter = 0;

    int i;
    const char* word;
    for (i = 1; i < argc; i++) {
        word = argv[i];
        hashmap* result = get_word_from_results(&results, results_counter, word);
        // If result is NULL, means word is not inserted yet, let's create a new hashmap and insert it inside the array
        if (result == NULL) {
            hashmap h;
            h.counter = 1;
            h.word = (unsigned char *)word;

            results = realloc(NULL, (results_counter + 1) * sizeof(hashmap) );
            // NOTE: potential memory leak? would h be deallocated?
            results[results_counter] = h;
            results_counter++;
            printf("NEW\n");
        } else {
            // The word already exists in the hashmap array, let's increase it by 1
            result->counter++;
            printf("INCREMENTED\n");
        }
    }   
    return 0;
}

谁能给我一些建议?我在这里做错了什么?我的指针还好吗?我还想我发现了内存泄漏(见评论),有人愿意提交他们的版本吗?

谢谢!!你们太酷了!!

丹尼尔

4

1 回答 1

1

程序中的主要指针问题是当第一次hashmap* results传递给realloc时,它的值是未初始化的。这是未定义的行为。您应该初始化指向 的指针NULL,如下所示:

hashmap* results = NULL;

另一个问题是比较字符串:您需要使用strcmp而不是==. 请记住,strcmp当字符串相等时返回零。

程序结束时也存在内存泄漏。您应该 free results,以及存储在其元素中的单词。

当然,您调用的东西的hashmap行为就像动态数组一样。然而,用 C 语言编写哈希表会带来不同程度的挑战,因此我鼓励您使用当前的方法。

于 2012-07-13T10:49:50.233 回答