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

pre*_*lic 1 c

我有点困惑.

我正在编写一个非常简单的文件系统,它基本上是: -
从一个文件中
读取一个数据块 - 从该块中
获取一个哈希
- 搜索该哈希的链接列表- 如果找不到,请附加
- 如果找到,则不执行任何操作

问题:
当我不使用free时,程序要慢得多(可能是泄漏?).

当我使用free时,程序运行得更快,块大小为128和256,但是当我尝试512(插入时崩溃)时崩溃.我在视觉工作室工作,它只是崩溃了.我得到"VS停止工作......"的消息,没有提供任何见解.

最重要的是,当我使用free而不使用它时,我会得到很多不同的结果.

任何帮助将非常感谢.

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

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;
}
Run Code Online (Sandbox Code Playgroud)

thk*_*ala 6

在你的ins()功能中你:

  • malloc()记忆和iterator用来指向它

  • 稍后您会做一些语句iterator = head,这意味着您丢失了指向已分配内存区域的指针并且存在重大内存泄漏

  • 接下来的一些声明是你做/不做(取决于注释)free()迭代器指向的项目,当它仍然 在你的列表中时,你可能想要释放该区域malloc()

编辑:

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

编辑2:

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

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

另外两点:

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

  • Visual Studio有一个调试器(我被告知)非常好.学习如何使用它会对你有很大帮助.