Visual c++ 为什么要释放calloc';我的VC6项目内存崩溃?

Visual c++ 为什么要释放calloc';我的VC6项目内存崩溃?,visual-c++,memory-management,visual-c++-6,gmp,Visual C++,Memory Management,Visual C++ 6,Gmp,比较这两个基本相同的函数。在第一种情况下,buff的内存是使用_alloca分配的。这个很好用。在第二种情况下,使用calloc和free代替_alloca。这会崩溃 奇怪的是,我在几乎所有其他GMP包装功能中都使用了calloc/free技术,它们都能正常工作。这里没有。有什么想法吗 1: 2: 这可能是不相关的,但这种类型的“一种方式工作,但另一种方式不工作”通常表示一个bug在一种情况下恰好通过,但在另一种情况下会导致致命错误 如果您怀疑可能发生内存覆盖,您可以尝试在缓冲区中分配额外的8字

比较这两个基本相同的函数。在第一种情况下,
buff
的内存是使用_alloca分配的。这个很好用。在第二种情况下,使用calloc和free代替_alloca。这会崩溃

奇怪的是,我在几乎所有其他GMP包装功能中都使用了calloc/free技术,它们都能正常工作。这里没有。有什么想法吗

1: 2:
这可能是不相关的,但这种类型的“一种方式工作,但另一种方式不工作”通常表示一个bug在一种情况下恰好通过,但在另一种情况下会导致致命错误


如果您怀疑可能发生内存覆盖,您可以尝试在缓冲区中分配额外的8字节,并写入4字节的开始和结束哨兵,然后在释放之前进行检查

这可能是不相关的,但这种类型的“一种方式工作,但另一种方式不工作”通常表示一个bug在一种情况下恰好通过,但在另一种情况下会导致致命错误


如果您怀疑可能发生内存覆盖,您可以尝试在缓冲区中分配额外的8字节,并写入4字节的开始和结束哨兵,然后在释放之前进行检查

有一次,我花了一个星期的时间想弄明白一件类似的事情。缓冲区溢出导致指针被丢弃,自由的指针被扔进了树林。RationalPurify很快就发现了这个问题

有一次,我花了一个星期的时间想弄明白一件类似的事情。缓冲区溢出导致指针被丢弃,自由的指针被扔进了树林。RationalPurify很快就发现了这个问题

添加日志记录并在过程中转储所有内容,以查找出错的地方。这通常比猜测更有效。

添加日志记录,并在过程中转储所有内容,以发现哪里出了问题。这通常比猜测更有效。

如果出现错误(如内存不足),calloc可能会返回NULL。我建议检查任何内存分配函数的结果是否为空。如果为NULL,则打印一条消息,然后退出(1)。

如果出现错误(如内存不足),calloc可能会返回NULL。我建议检查任何内存分配函数的结果是否为空。如果为空,则打印一条消息,然后退出(1)。

\u alloca
返回堆栈内存,因此踩过堆栈末尾可能不一定会覆盖重要内容。写入超过堆内存分配末尾的内容更有可能覆盖某些重要内容


您的代码无法确保缓冲区的大小至少与n1除以n2后的
res
格式相同(反之亦然,因为我不知道实际函数的作用);它只确保它有足够的内存用于初始化的
res
,这可能是1。如果
n1/n2
的位数多于此数,欢迎来到crashville。

\u alloca
返回堆栈内存,因此踩过堆栈末尾可能不一定会覆盖重要内容。写入超过堆内存分配末尾的内容更有可能覆盖某些重要内容


您的代码无法确保缓冲区的大小至少与n1除以n2后的
res
格式相同(反之亦然,因为我不知道实际函数的作用);它只确保它有足够的内存用于初始化的
res
,这可能是1。如果
n1/n2
的数字比这多,欢迎来到crashville。

@johnny指出了一些相当尴尬的事情,这需要重写代码。(在这里,能够勾选评论会很有用。)


在以前的版本中,内存是根据代码中包含零的点处的
res
值分配的。因此,我试图调用零字节,而free不喜欢它。在上面的代码中,
res
实际上包含了一些
mpz_sizeinbase
可以使用的东西。

@johnny指出了一些相当尴尬的事情,需要重写代码。(在这里,能够勾选评论会很有用。)


在以前的版本中,内存是根据代码中包含零的点处的
res
值分配的。因此,我试图调用零字节,而free不喜欢它。在上面的代码中,
res
实际上包含
mpz_sizeinbase
可以使用的内容。

核心转储说明了什么?或者你没有得到一个?顺便说一句,alloca是不推荐的,使用malloca instead会猜测在新初始化的结构上使用的mpz_sizeinbase()应该返回0。有了alloca,你的缓冲区就在堆栈上了,它会把已经存在的几个结构都扔掉(而且可能不会崩溃)。(脸红得厉害)我想你在这里已经一针见血了@johny。阿洛卡肯定是在“错误的地方”。遗憾的是一个人不能勾选评论。我不明白为什么不能使用alloca。核心转储说什么?或者你没有得到一个?顺便说一句,alloca是不推荐的,使用malloca instead会猜测在新初始化的结构上使用的mpz_sizeinbase()应该返回0。有了alloca,你的缓冲区就在堆栈上了,它会把已经存在的几个结构都扔掉(而且可能不会崩溃)。(脸红得厉害)我想你在这里已经一针见血了@johny。阿洛卡肯定是在“错误的地方”。遗憾的是,一个人不能勾选注释。我不明白为什么不能使用_alloca。即使很无聊,你也必须始终检查calloc之类的返回值……如果calloc返回null,崩溃会发生得更早。即使很无聊,您必须始终检查calloc之类的返回值……如果calloc返回null,则崩溃将发生得更早。
#define Z(x) mpz_t (x); mpz_init( (x) );
#define BUFF_SIZE (1024 * 32)

BSTR __stdcall IBIGDIV(BSTR p1, BSTR p2 ) { 
    USES_CONVERSION;

    Z(n1);
    Z(n2);
    Z(res);

    char * buff =  (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 );

    LPSTR sNum1 = W2A( p1 );
    LPSTR sNum2 = W2A( p2 );

    mpz_set_str( n1, sNum1, 10 );
    mpz_set_str( n2, sNum2, 10 );

    if ( mpz_sgn( n2 ) != 0 ) { 
        mpz_div( res, n1, n2 );
        mpz_get_str(buff, 10, res);
    } else {
        strcpy( buff, "-0" );
    }

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    return bResult;
}
#define Z(x) mpz_t (x); mpz_init( (x) );
#define BUFF_SIZE (1024 * 32)

BSTR __stdcall IBIGDIV(BSTR p1, BSTR p2 ) { 
    USES_CONVERSION;

    Z(n1);
    Z(n2);
    Z(res);

    char * buff =  (char *) calloc( mpz_sizeinbase( res, 10 ) + 2, sizeof( char ) );

    LPSTR sNum1 = W2A( p1 );
    LPSTR sNum2 = W2A( p2 );

    mpz_set_str( n1, sNum1, 10 );
    mpz_set_str( n2, sNum2, 10 );

    if ( mpz_sgn( n2 ) != 0 ) { 
        mpz_div( res, n1, n2 );
        mpz_get_str(buff, 10, res);
    } else {
        strcpy( buff, "-0" );
    }

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    free( buff );
    return bResult;
}
BSTR __stdcall IBIGDIV(BSTR p1, BSTR p2 ) { 
    USES_CONVERSION;

    Z(n1);
    Z(n2);
    Z(res);

    char * buff;

    LPSTR sNum1 = W2A( p1 );
    LPSTR sNum2 = W2A( p2 );

    mpz_set_str( n1, sNum1, 10 );
    mpz_set_str( n2, sNum2, 10 );

    if ( mpz_sgn( n2 ) != 0 ) { 
        mpz_div( res, n1, n2 );
        buff =  (char *) calloc( mpz_sizeinbase( res, 10 ) + 2, sizeof( char ) );
        mpz_get_str(buff, 10, res);
    } else {
        buff =  (char *) calloc( 3, sizeof( char ) );
        strcpy( buff, "-0" );
    }

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    free( buff );
    return bResult;
}