【问题标题】:How can I free memory and at the same time return a pointer?如何释放内存并同时返回指针?
【发布时间】:2020-10-28 19:28:59
【问题描述】:

我有这些功能

char *hash(char *stringa, char *tipohash) {
    if (strcmp(tipohash, "md5") == 0) {
        stringa = md5(stringa);
    }
    return stringa;
}

char *md5(char *stringa) {
    unsigned char risultato[MD5_DIGEST_LENGTH];
    int i;
    char *hashfinale = malloc(sizeof(char) * MD5_DIGEST_LENGTH * 2);
    MD5((const unsigned char *)stringa, strlen(stringa), risultato);
    for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
        sprintf(hashfinale + 2 * i, "%02x", risultato[i]);
    }
    return (char *)hashfinale;
}

如何在不丢失字符串值的情况下返回(char *)hashfinale

这是来电者

char *hashlinea = hash(stringa, hashType);

【问题讨论】:

  • 将该函数记录为返回一个需要传递给free的指针,并让被调用者处理它。
  • 或者您可以修改签名以获取指向数组第一个字符的指针(加上数组的长度)并使用它,而无需您的函数进行任何动态分配。
  • @Someprogrammerdude 我不明白你在说什么
  • 问题是,如果你释放函数中的指针,它就不再可用,所以返回它会调用未定义的行为,你应该像你一样返回指针,并在你调用的任何地方释放它使用返回的指针后的函数。
  • 我不明白你的问题是什么。是否要返回指向字符串的指针?如果是,则需要返回一个未释放的指针。如果不是,为什么要返回指针/值?

标签: c memory memory-management malloc free


【解决方案1】:

这是不可能的。 IMO 最好将指针传递给缓冲区。调用者将负责内存管理

char *md5(char *stringa, char *hashfinale){
 ...
}

【讨论】:

  • 问题是如果从调用者那里释放它会填满内存,所以我想我必须在被调用者中释放它
  • @helloworld 你的整个想法似乎不完整。我提示您问题的评论部分。如果您更多地考虑自己想要做什么,这种方法是最好的方法。
  • 虽然这个答案在信息方面有点少见,但我还是投了赞成票,因为它显示了大概正确的解决方案。
【解决方案2】:

解决问题基本上有两种方法,都没有涉及到你的代码调用free


第一种方法是与现在不做任何不同的事情,除了添加文档以便hash 函数的用户知道代码必须在返回的指针上调用free

// This is the code using your function
char *hashlinea = hash(stringa,hashType);

// Some code using hashlinea

free(hashlinea);

第二种方法是传递一个指向现有数组的指针,您的代码使用该数组而不是使用malloc 分配它:

char hashlinea[MD5_DIGEST_LENGTH*2];
hash(stringa, hashType, hashlinea);

为此,您的hash 函数需要将第三个参数传递给md5 函数,它应该使用它而不是分配内存:

char *md5(char *stringa, char *hashfinale){
    unsigned char risultato[MD5_DIGEST_LENGTH];
    int i;
    // No memory allocation here
    MD5((const unsigned char *)stringa, strlen(stringa), risultato);
    for(i = 0; i < MD5_DIGEST_LENGTH; i++) {
        sprintf(hashfinale + 2*i,"%02x",risultato[i]);
    }
    return hashfinale;
}

【讨论】:

    【解决方案3】:

    您的md5 函数存在问题:为 MD5 哈希分配的大小必须比空终止符长一个字节:

    char *hashfinale = malloc(sizeof(char) * (MD5_DIGEST_LENGTH * 2 + 1));
    

    请注意,在 C(和 C++)中,sizeof(char) 的定义是 1,所以你可以写:

    char *hashfinale = malloc(MD5_DIGEST_LENGTH * 2 + 1);
    

    关于您的问题,hash 返回其参数或分配的对象。这是内存管理的问题,因为您可能在程序后面不知道是否必须释放返回值。传递散列字符串的目标数组是更好的选择,否则您应该复制字符串,以便可以无条件释放 hash 的返回值:

    char *md5(const char *stringa) {
        unsigned char risultato[MD5_DIGEST_LENGTH];
        int i;
        char *hashfinale = malloc(MD5_DIGEST_LENGTH * 2 + 1);
        MD5((const unsigned char *)stringa, strlen(stringa), risultato);
        for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
            sprintf(hashfinale + 2 * i, "%02x", risultato[i]);
        }
        return hashfinale;
    }
    
    // always free the return value
    char *hash(const char *stringa, const char *tipohash) {
        if (!strcmp(tipohash, "md5")) {
            return md5(stringa);
        } else {
            return strdup(stringa);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      • 2022-09-27
      • 2014-03-28
      • 2021-07-30
      • 1970-01-01
      相关资源
      最近更新 更多