字符指针返回值垃圾

Char Pointer Return Value Garbage

本文关键字:返回值 指针 字符      更新时间:2023-10-16

我想使用Linux库(文档)中的SHA1函数,该函数返回无符号的char指针。据我所知,它创建了一个新的数组,但这不意味着我必须释放用于它的内存吗?我如何知道我应该使用free还是delete[]?我想这个特定的函数使用C的方式来分配内存,但我怎么知道呢?有些C++函数返回的是char数组,而不是std::string。

请记住,虽然它可能使用malloc分配了堆上的内存,但它也可能返回一个指向函数作用域专用的静态固定长度数组的指针。这对于Linux上的库函数来说并不罕见,尤其是那些不可重入的函数。因此,如果在指向静态数组的指针上调用free(),就会得到某种类型的未定义行为。

例如,从SHA1():文档的这一部分

SHA1()计算d处n个字节的SHA-1消息摘要将其放置在md中(必须有空间用于SHA_DIGEST_LENGTH==20输出的字节)。如果md为NULL,则将摘要置于静态大堆

在我看来,返回指针要么指向您通过md参数输入的数组,要么,如果md参数是NULL,则返回指针指向函数专用的静态数组。我没有看到任何地方提到必须显式释放函数返回的指针。

唯一通用且正确的答案是:阅读文档。您使用的每个外部函数都必须在其文档中告诉您它期望什么样的输入以及返回什么。

如果它说它返回一个指向用malloc(或等效值)分配的内存的指针,那么您必须自己free它。

(实际上,有时您可能可以运行valgrind,并根据报告进行有根据的猜测,但这并不是一个"解决方案",因为它是猜测。)

您应该使用evp_*函数,而不是您引用的那些较低级别的函数。那里有销毁和创建摘要的功能。

unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md);

根据文档,除非是md==0,否则返回值为md。如果是md==0,则它被放置在一个静态数组中,因此您不必担心。我写了下面的代码来证明这个概念。

#include <openssl/sha.h>
#include <string.h>
#include <stdio.h>
void print_hash( const unsigned char* c )
{
    printf( "The hash is: " );
    int index;
    for(index = 0; index < SHA_DIGEST_LENGTH; index++)
        printf( "%X", *c++ );
    printf( "n" );
}
int main(int argc, char* argv[])
{
    unsigned char hash[SHA_DIGEST_LENGTH];
    unsigned char str[100];
    scanf( "%s", str );
    unsigned char* sha = SHA1(str, strlen((char*)str), hash);
    print_hash( hash );
    print_hash( sha );
    print_hash( SHA1(str, strlen((char*)str), 0) );
}

结果:

some example input
The hash is: EB875812858D27B22CB2B75F992DFFADC1B05C66
The hash is: EB875812858D27B22CB2B75F992DFFADC1B05C66
The hash is: EB875812858D27B22CB2B75F992DFFADC1B05C66

哈希的存储方式由您决定。