0

Python や JS などの動的言語でのプログラミングを約 5 年間行った後、内部で起こっていることを見逃していると感じ始めています。このような言語は、ポインター、メモリ割り当て、および多くの検索、並べ替え、挿入アルゴリズムを処理するという問題を利用して、やらなければならないことに集中できるため、非常に優れています。これらの言語を使用したことを後悔したことはありませんが、これらの言語はとてつもなく強力であると感じていますが、より良いプログラマーになるためには、一歩下がって内部で何が起こっているのかを理解する必要があると感じています!

私は簡単な単語カウンターを書くことでこれを行うことにしました: アプリはすべてのパラメーターを取得し、すべての一意の単語を出力します。実際の出力構造は考慮していません)。このプログラムは、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もう1つの問題は、文字列の比較です。ではなくを使用する必要があります==strcmp文字列が等しい場合はゼロを返すことに注意してください。

プログラムの最後にもメモリリークがあります。results要素内に格納されている単語とともに、を解放する必要があります。

もちろん、あなたが呼ぶものhashmapは動的配列のように正確に振る舞います。ただし、Cでハッシュテーブルをプログラミングすると、さまざまなレベルの課題が発生するため、現在のアプローチを機能させることをお勧めします。

于 2012-07-13T10:49:50.233 に答える