【问题标题】:Allocating Memory for an Array of SHA1 Digests为 SHA1 摘要数组分配内存
【发布时间】:2013-10-09 23:16:35
【问题描述】:

我有一个小程序,它为通过命令行传递的参数生成一个 SHA1 摘要并将它们存储在一个指向 char 数组的指针数组中(我认为):

#include <stdio.h>
#include <openssl/sha.h>

int entries = 0; // Keep track of entries added

int main(int argc, char **argv)
{
    // Allocate space for the digest array
    unsigned char **mds = malloc(1);

    // Add entries to the digest, one for each argument passed  
    for(int k = 1; k < argc; k++) {
        mds[k - 1] = malloc(SHA_DIGEST_LENGTH);
        SHA1(argv[k], strlen(argv[k]), mds[k - 1]);
        entries++;
    }

    // Print each 20-byte digest
    for(int j = 0; j < entries; j++) {
        for(int i = 0; i < SHA_DIGEST_LENGTH; i++) { printf("%02x ", *(mds[j] + i)); }
        printf("\n");
    }
}

最初我有unsigned char **mds = calloc(argc, SHA_DIGEST_LENGTH);,每次我想添加另一个条目时我都会尝试使用realloc()(如果我不知道以后会有多少条目的话)。

但后来我发现我不需要这样做,甚至根本不需要分配任何空间?只是一个字节,它仍然可以正常工作。这对我来说似乎不对。

我只是运气好还是什么?我错过了什么?

【问题讨论】:

    标签: c arrays pointers char malloc


    【解决方案1】:

    我只是走运了还是怎么了?

    是的。

    我错过了什么?

    您的程序在分配的内存之外写入。这样做会导致未定义的行为。任何事情都可能发生,包括正确行为的出现。

    添加一些 free() 调用可能会导致一些崩溃,但不能保证 - 毕竟未定义的行为是未定义的。

    【讨论】:

    • 所以我应该保留unsigned char **mds = calloc(argc, SHA_DIGEST_LENGTH); 并在我不知道argc 的情况下在循环中使用realloc(),对吗?
    • 为什么不先分配argc 条目呢? calloc 的电话似乎很奇怪。
    • 如果我实际上不知道我将拥有多少条目,而不是采用 CL 参数。
    • ... 但是argc 告诉你有多少命令行参数。
    • 是的,我知道,但是如果我要将这段代码移动到另一个程序内部的自己的函数中,其中要散列的字符串实际上并没有通过命令行传递。
    【解决方案2】:

    您正在写入未分配给您的内存。幸运的是,到目前为止您还没有崩溃。

    如果您的平台上可用,请尝试使用 valgrind。它会告诉你这种类型的内存错误以及你何时分配你忘记释放的内存。该程序运行速度会较慢,但您只需进行测试即可。

    【讨论】:

    • 感谢关于 Valgrind 的建议,我一定会用的!
    【解决方案3】:

    这部分:

    // Allocate space for the digest array
    unsigned char **mds = malloc(1);
    

    分配大小为1 字节的内存块并将其地址转换为unsigned char**。然后在第一次迭代的后期,当你这样做时:

    mds[k - 1] = malloc(SHA_DIGEST_LENGTH);
    

    malloc 返回一个地址,该地址被写入无效内存,导致未定义行为


    您需要分配适当的内存块来保存 pointers,并且在每次迭代中,您将初始化每个指针以指向将保存 string 的内存块:

    // allocate array of pointers:
    unsigned char **mds = malloc( (argc - 1) * sizeof(unsigned char*) );
    
    for (int k = 1; k < argc; k++) {
        mds[k - 1] = malloc(SHA_DIGEST_LENGTH);
        SHA1(argv[k], strlen(argv[k]), mds[k - 1]);
        entries++;
    }
    ...
    // cleaning up:
    for (int k = 1; k < argc; k++) {
        free(mds[k - 1]);
    }
    free(mds);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-18
      • 2020-10-23
      • 2014-04-21
      • 2015-02-01
      • 2012-03-23
      • 1970-01-01
      相关资源
      最近更新 更多