c - 使用 free() 时程序发生奇怪的变化

标签 c

我有点困惑。

我正在编写一个非常简单的文件系统,基本上:
- 从文件中读取数据 block
- 从该 block 中获取哈希值
- 在链表中搜索该散列
-如果没有找到,追加
-如果找到,什么都不做

问题:
当我不使用 free 时,程序会慢很多(可能是泄漏?)。

当我使用 free 时,程序运行得更快,以 128 和 256 的 block 大小完成,但是当我尝试 512 时程序崩溃(插入时崩溃)。我在 Visual Studio 工作,它就崩溃了。我收到“VS 停止工作..”消息,但没有提供任何见解。

最重要的是,当我使用免费版和不使用免费版时,我得到的结果大不相同。

非常感谢任何帮助。

好的,一些代码(缩写):

struct list_el
{
    char* hash;
    struct list_el* next;
    struct list_el* prev;
};  
typedef struct list_el item;

item* head, *tail;

void ins(item* ins) 
{
item* iterator = (item*)malloc(sizeof(item));
if(iterator == NULL)
{
    printf("out of memory\n");
    exit(1);
}
else if(head != NULL)
{
    iterator = head;
    while(iterator != NULL)
    {
        if(strcmp(iterator->hash, ins->hash) == 0)
        {
            //free(iterator); (problem line)
            matches++;
            return;
        }
        else if(iterator->next != NULL)
            iterator = iterator->next;
        else
            break;

    }
}

unique_blocks++;
if(head == NULL) 
{
    head = ins;
    ins->prev = NULL;

}

else 
{
    tail->next = ins;
    ins->prev = tail;
}

tail = ins;
ins->next = NULL;
}


int main()
{
unsigned char* c = (unsigned char*)malloc(BLOCKSIZE+1);
if(c == NULL)
    exit(1);
FILE* fp = fopen("input2","r");
if(fp == NULL)
    exit(1);
int i = 0;

char* answer = (char*)malloc(sizeof(char)*90);
if(answer == NULL)
    exit(1);
item* ins_item;
char ch;
do
{
    if(i == BLOCKSIZE)
    {       
        i = 0;
        answer = sha1((unsigned char*)c);
        ins_item = (item*)malloc(sizeof(item));
        if(ins_item == NULL)
            exit(1);
        ins_item->hash = answer;
        ins(ins_item);

    }
    else
    {
        ch = fgetc(fp);
        bytes_read++;
        c[i] = ch;
        i++;
    }
}while(ch != EOF);
fclose(fp);
return 0;
}

最佳答案

在您的 ins() 函数中:

  • malloc() 内存并使用iterator 指向它

  • 几条语句之后您执行了 iterator = head,这意味着您丢失了指向已分配内存区域的指针并且发生了严重的内存泄漏

  • 然后在你做/不做之后的一些声明(取决于评论) free() 迭代器指向的项目 仍然 在您的列表中,虽然您可能想从 malloc()

  • 中释放该区域

编辑:

为什么要给迭代器分配内存?通常列表迭代器是简单的指针,指向代码当前正在检查的任何项目。

编辑 2:

崩溃很可能是由于您的程序访问了仍在列表中的已释放(因此可用)内存。

释放的内存不一定返回给系统。根据堆分配器的工作方式,它甚至可以通过另一个 malloc() 调用再次分配给您的程序。当您的程序尝试再次访问它时,它可能拥有与预期非常不同的数据。

另外两点:

  • 让您的标识符在同一范围内保持唯一。它可能不会让编译器停止,但它肯定会让人脑停止。例如。你不应该有一个带有 ins 参数的 ins() 函数。

  • Visual Studio 有一个调试器(我听说)非常好。学习如何使用它会帮助你很多

关于c - 使用 free() 时程序发生奇怪的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4396862/

相关文章:

c - 从 rs232 读取多个字节到 uart (avr atmega16)

人物比较

c - C 中的 2+2=2(双重算术)

python - mingw32-gcc 编译 Cython 输出 : unknown multiarch location for pyconfig. h (和其他警告)

无法将 int 打印到文件

c - 意外的结果 - 寻找最大值和第二最大值

c - 与左节点比较后删除节点

c - 如何更改通过引用传递给函数的字符串的值?

c - 编译pthreads程序时出现问题

c - 如何扫描除第一行以外的行中的值