C - free()出错?

时间:2017-05-17 07:41:09

标签: c

我正在制作一些哈希函数。

它的源代码是......

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int m_hash(char *input, size_t in_length, char *output, size_t out_length);

int main()
{
    char buffer[1025];
    char output[65];
    output[64] = '\0';
    while(1)
    {
        printf("enter what will hash : ");
        fgets(buffer, 1024, stdin);
        buffer[1024] = '\0';
        m_hash(buffer, strlen(buffer), output, 64);
        printf("your string (hashed) : %s\n", output);
    }
    return 0;
}

int m_hash(char *input, size_t in_length, char *output, size_t out_length) // 0 on Success, 1 on Fail.
{
    const char OUT[64] = "zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP1234567890_-";
    char *snow = (char *)malloc(sizeof(char) * out_length);
    if (snow == NULL) return 1;
    int *out = (int *)malloc(sizeof(int) * out_length);
    if (out == NULL)
    {
        free(snow);
        return 1;
    }
    memset(out, 0x00, sizeof(int) * out_length);
    size_t tmp = 0, i, j;
    for (i = 0; i < out_length; i++)
    {
        tmp += i * i;
        snow[i] = tmp / (i + 1);
        tmp -= snow[i];
    }
    for (i = 0; i < in_length; i++)
    {
        out[((tmp *= (i + 1)) % out_length + out_length) % out_length] += input[i];
        snow[i] += input[i];
        for (j = 0; j < out_length; j++)
        {
            out[((i + j) % out_length + out_length) % out_length] += snow[j] % (i + 1);
        }
    }
printf("Will free snow.\n");
    free(snow); // ERROR WTF?
printf("Freed snow.\n");
    for (i = 0; i < out_length; i++)
    {
        output[i] = OUT[(out[i] % 64 + 64) % 64];
    }
    free(out);
    return 0;
}

当我输入短字符串时,没有错误。但是当我输入像这样的长串... It's seems to free() makes error... '免费(雪);'?!?!!

有错误

Visual Studio的调试信息是......     HEAP CORRUPTION DETECTED:在正常块(#92)之后的0x01505D08。     CRT检测到应用程序在堆缓冲区结束后写入内存。

我真的不知道这有什么不对......

出了什么问题......? ㅠ。ㅜ

3 个答案:

答案 0 :(得分:0)

没有调试它发生的确切位置 - &gt;在某些时候,你在你分配的记忆之前/之后写作。这会覆盖在程序运行时不会影响程序的分配元数据,但是当您尝试释放内存时,您会发现垃圾并崩溃。

如果您运行的是Linux,我建议您尝试valgrind进行调试,但显然还有一些Windows选项:Is there a good Valgrind substitute for Windows?

基本上你想要的东西会在你写出界限时出错,而不是当你试着读回来时。

答案 1 :(得分:0)

问题来自malloc'd make缓冲区不足。 你将它的大小为out_length(snow)。

虽然你用in_length循环它(当out_length是64时,最多1024个):

char *snow = (char *)malloc(sizeof(char) * out_length);

在这个街区的第三行,当我&gt; 64,你得到一个内存错误,最有可能导致内存损坏,导致程序在for (i = 0; i < in_length; i++) { out[((tmp *= (i + 1)) % out_length + out_length) % out_length] += input[i]; snow[i] += input[i]; for (j = 0; j < out_length; j++) { out[((i + j) % out_length + out_length) % out_length] += snow[j] % (i + 1); } } 崩溃。

答案 2 :(得分:0)

正如上面的评论所指出的,in_length > out_length的可能性更大。这也支持你的事实,它会在非常长的字符串中崩溃。

因此,您可能希望支持在snow之前通过realloc增加for (i = 0; i < in_length; i++)的大小

if (in_length > out_length) {
    int additional_bytes =  in_length - out_length;
    snow = realloc(snow, sizeof(char) * (out_length + additional_bytes));
}