简体   繁体   中英

Char Pointer Return Value Garbage

I want to use SHA1 function from Linux libraries ( documentation ) which returns unsigned char pointer. As I understand it creates a new array but doesn't it mean I have to free the memory used for it? And how do I know whether I should use free or delete[]? I guess this particular functions uses C way of allocating memory but how do I know in general? Some C++ functions return char arrays rather than std::string.

Keep in mind while it might have allocated the memory on the heap using malloc , it could also be returning a pointer to a static fixed-length array private to the scope of the function. That's not untypical for library functions on Linux, especially those that are not re-entrant. So if you call free() on a pointer that is pointing to a static array, you're going to get some type of undefined behavior.

For instance, from this segment of the documentation for SHA1() :

SHA1 () computes the SHA-1 message digest of the n bytes at d and places it in md (which must have space for SHA_DIGEST_LENGTH == 20 bytes of output). If md is NULL , the digest is placed in a static array.

it looks to me like the return pointer is either going to be pointing to the array you've input via the md argument, or, if the md argument is NULL , the return pointer is pointing to a static array private to the function. Nowhere do I see it mentioned that you must explicitly free the pointer returned by the function.

The only general and correct answer: Read the documentation. Every foreign function that you use must tell you in its documentation what sort of input it expects and what it returns.

If it says that it returns a pointer to memory allocated with malloc (or equivalent), you must free it yourself.

(Practically, you might sometimes perhaps be able to run valgrind and base an educated guess on the report, but that's not a "solution" in as much as it is guesswork.)

You should be using the evp_* functions rather than those lower level functions that you referenced. There are functions there for destroying and creating the digests.

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

According to the documentation, unless md==0 , the return value is md. If md==0 , it's placed in a static array, so you don't have to worry about it. I wrote the fallowing to prove the concept.

#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) );
}

Results:

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

How the hash is stored is up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM