【问题标题】:Freeing memory after passing value causing EXC_BAD_ACCESS传递值后释放内存导致 EXC_BAD_ACCESS
【发布时间】:2014-11-19 16:53:55
【问题描述】:

当我在将foo 中的normalizedWord 传递给AddElement 后释放normalizedWord 时,尝试使用key 执行strcmp 时出现段错误。没有释放,除了巨大的内存泄漏之外,没有任何问题。知道这里可能发生了什么吗?

foo(char* word)
{
    char* normalizedWord = (char*)(malloc(strlen(word) + 1);
    strcpy(normalizedWord, word);

    Normalize(normalizedWord);
    int result = AddElement(dict->hashTable, normalizedWord);

    free(normalizedWord);
    return result;
}

AddElement(HashTable *hashTable, const char *key)
{
    if (0 == hashTable->elements[hashIndex])
    {
        // Add new element
        hashTable->elements[hashIndex] = CreateElement(key);
    }
    else
    {
        // Search for existing or Add new element
        Element* current = hashTable->elements[hashIndex];

        /* ERROR HERE... */
        while (0 != strcmp(current->key, key))
        {
            if (NULL == current->next)
            {
                current->next = CreateElement(key);
                break;
            }
            else
            {
                current = current->next;
            }
        }
    }

    return 0;
}

Element* CreateElement(const char* key)
{
    Element* element;

    if (NULL == (element = malloc(sizeof(element))))
    {
        return NULL;
    }

    element->key = (char*) malloc(strlen(key) + 1);
    strcpy(element->key, key);

    return element;
}

【问题讨论】:

  • 也许Normalize 做了坏事?
  • 缺少以下信息: 1. 函数Normalize的实现。 2. 调用函数foo。 3、全局变量dict的声明、实例化和初始化。
  • CreateElement() 中,您需要将新元素的next 指针设置为NULL...AddElement() 可能正试图越过列表末尾移动到无效节点。
  • 一些编码建议: 1. 尽量避免使用全局变量。 2.摆脱if (constant value == something)的约定。的确,它是“发明”的,目的是防止您误用 = 而不是 ==,但这只会使代码的可读性降低。确保使用== 来保护自己。 3. 在同一个问题上,从if (NULL == (element = ...))) 语句中取出赋值。
  • 4.避免转换malloc 的返回值。 5. 当您在代码中的其他任何地方与NULL 进行适当比较时,为什么还要使用if (0 == hashTable->elements[hashIndex])

标签: c memory-management memory-leaks free


【解决方案1】:

除了 Illuminatus pr 指出的未初始化的element->next,您分配的内存的大小 有问题。声明

Element* element = malloc(sizeof(element));

为一个指针分配足够的内存,而不是实际元素。你需要写的是这样的:

Element* element = malloc(sizeof(*element));

唯一的区别是额外的星号,它可以在分配八个字节或千字节之间产生区别。

【讨论】:

  • 这解释了我在 valgrind 中看到的一些内容。
【解决方案2】:

我可以看到的一个问题是element->next 在创建元素时未初始化。很明显next 不是静态成员,因此当添加第一个元素时,其next 值将包含垃圾。正因为如此,current 被以下代码部分分配了一些垃圾值:

else
{
    current = current->next;
}

导致 strcmp() 中的段内存访问不足;

CreateElement() 函数中添加element->next=NULL; 可能会修复此分段错误。

【讨论】:

  • 这绝对是问题所在,正如 Dmitri 在上面的 cmets 中指出的那样。由于 Dmitri 没有提交答案,因此暂时选择您作为正确答案。感谢您的观看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 2021-08-23
  • 2022-01-05
相关资源
最近更新 更多