Leetcode上的运行时错误

时间:2018-03-02 05:47:37

标签: c

当我将代码提交给Leetcode时,它将运行时错误报告为:

第43行:类型为' struct bucket_item'的空指针内的成员访问。

我在当地测试了这个案例,它运作正常。我认为它可能是由平台和编译器造成的不同。然后我尝试在Leetcode Playground上测试它。它也运作得很好。 Leetcode问题是:https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

非常感谢,如果有人能让我知道我的代码有什么问题。

typedef struct bucket_item {
    char *str;
    int count;
    int ori_count;
} bucket_item;

typedef struct bucket {
    int hashIndex;
    int itemsCount;
    bucket_item *items;
} bucket;

bucket *hash_init(const int bucket_count)
{
    bucket *buckets = malloc(sizeof(bucket) * bucket_count);
    for (int i = 0; i < bucket_count; ++i)
    {
        buckets[i].items = NULL;
        buckets[i].itemsCount = 0;
    }
    return buckets;
}

int get_hash(char *str, const int bucket_count) {
    const int str_len = strlen(str);
    int base = 0;
    int i = 0;
    while (str[i] != '\0')
    {
        base += str[i];
        i++;
    }
    return ((base >> 3) * 2654435761) % bucket_count;
}

bucket_item *hash_lookup(bucket *buckets, char *str, const int bucket_count)
{
    const int hash_index = get_hash(str, bucket_count);
    bucket *bucket = buckets + hash_index;

    for (int i = 0; i < bucket->itemsCount; ++i)
    {
        if (strcmp(str, bucket->items[i].str) == 0) return bucket->items + i;
    }
    return NULL;
}

void hash_add(bucket *buckets, char *str, const int bucket_count)
{
    bucket_item *item = hash_lookup(buckets, str, bucket_count);
    if (item)
    {
        item->count++;
        item->ori_count = item->count;
    }
    else {
        const int hash_index = get_hash(str, bucket_count);
        bucket *bucket = buckets + hash_index;
        bucket->itemsCount++;
        bucket->items = (bucket_item *)realloc(bucket->items, sizeof(bucket_item) * bucket->itemsCount);
        bucket->items[bucket->itemsCount - 1].str = str;
        bucket->items[bucket->itemsCount - 1].count = 1;
        bucket->items[bucket->itemsCount - 1].ori_count = 1;
    }
}

void hash_free(bucket *buckets, const int bucket_count)
{
    for (int i = 0; i < bucket_count; ++i)
    {
        free(buckets[i].items);
        buckets[i].items = NULL;
    }
    free(buckets);
    buckets = NULL;
}

bool is_match(char* str, bucket *hashmap, int bucket_count, char **words, int word_len, int word_size)
{
    bool found = true;
    char *subStr = malloc(sizeof(char) * (word_len + 1));
    subStr[word_len] = '\0';
    for (int i = 0; i < word_size; ++i)
    {
        memcpy(subStr, str + i * word_len, word_len);
        bucket_item *item = hash_lookup(hashmap, subStr, bucket_count);
        if (item)
        {
            item->count--;
        }
        else
        {
            found = false;
        }
    }
    free(subStr);
    subStr = NULL;

    for (int i = 0; i < word_size; ++i)
    {
        bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
        if (item->count != 0) {
            found = false;
        }
    }
    for (int i = 0; i < word_size; ++i)
    {
        bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
        item->count = item->ori_count;
    }
    return found;
}

/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {
    if (wordsSize == 0) return NULL;

    const int word_len = strlen(words[0]);

    // prepare hashmap
    bucket *hashmap = hash_init(wordsSize);
    for (int i = 0; i < wordsSize; ++i)
    {
        hash_add(hashmap, words[i], wordsSize);
    }

    // loop long string.
    int *ret = malloc(sizeof(int) * 1000);
    *returnSize = 0;
    const int s_len = strlen(s);
    const int sub_strlen = word_len * wordsSize;
    for (int i = 0; i < s_len; ++i)
    {
        const bool found = is_match(s + i, hashmap, wordsSize, words, word_len, wordsSize);

        if (found)
        {
            ret[*returnSize] = i;
            (*returnSize)++;
        }
    }
    hash_free(hashmap, wordsSize);
    ret = (int*)realloc(ret, sizeof(int) * (*returnSize));

    return ret;
}

报告错误的情况如下:

int main() {
    char *str = "ababaab";
    char **words[] = { "ab", "ba", "ba" };
    int returnSize = 0;

    int *result = findSubstring(str, words, 3, &returnSize);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

当你使用hash_lookup函数时,它会在某些情况下返回NULL。

为了在下一行中使用item-&gt; count,您可以访问NULL指针。

您应首先检查是否为NULL,然后使用 item-&gt; count

for (int i = 0; i < word_size; ++i)
        {
            bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
            if (item->count != 0) {
                found = false;
            }
        }
        for (int i = 0; i < word_size; ++i)
        {
            bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
            item->count = item->ori_count;
        }