【问题标题】:C usage of malloc inside a function函数内部 malloc 的 C 用法
【发布时间】:2015-04-24 03:44:24
【问题描述】:

我有以下功能:

char * decrypt(const char *p, int key) {
  char *tmp = malloc(strlen(p) + 1);
  for (int i = 0; p[i] != '\0'; i++) {
    if (p[i] >= 'A' && p[i] <= 'Z') {
      if (key <= p[i] - 'A')
        tmp[i] = p[i] - key;
      else
        tmp[i] = p[i] - key + 'Z' - 'A' + 1;
    } else if (p[i] >= 'a' && p[i] <= 'z') {
      if (key <= p[i] - 'a')
        tmp[i] = p[i] - key;
      else
        tmp[i] = p[i] - key + 'Z' - 'A' + 1;
    }
  }
  return tmp;
}

我正在为临时指针*temp 分配内存:

char *tmp = malloc(strlen(p) + 1);

但我不会在任何地方释放它。

据我所知,释放内存有 4 个选项:

  1. 在同一范围内使用free()(这对我来说是不可能的,因为我必须返回指针)
  2. 使用alloca(),并非每个编译器都支持(不是 ANSI C)
  3. malloc()函数外的指针并将该指针传递给函数,然后free()它在函数外
  4. 将返回的指针分配给一个变量并释放该变量

这是选项 #4 的代码:

char *var;
var = malloc(MAX);
var = decrypt("Hello", 1);
free(var);

当我为变量var 分配一个返回的指针时,我是否必须malloc(),因为该指针已经是malloc()ed?

我的问题是:

在函数中使用malloc() 的最佳方式是什么?

如果我选择第 4 个选项,在将返回的指针分配给它之前,我是否必须 malloc() 变量?

【问题讨论】:

    标签: c function pointers malloc alloca


    【解决方案1】:

    应该是:

    char *var = decrypt(whatever);
    // ...use var...
    free(var);
    

    我不知道您为什么要在代码示例中预先泄漏一些内存。

    您的计划 (3) 预先分配内存并让函数填充它也是可行的,但它会产生更冗长的代码,因为它引入了函数导致缓冲区溢出的可能性。

    alloca 不起作用,因为该空间在函数返回时被释放。

    【讨论】:

    【解决方案2】:

    您可以修改decrypt 函数的签名,以便它提供函数写入结果的指针。

    void decrypt(char* dest, const char *p, int key);
    

    这样,管理这个内存空间是调用者的全部责任。

    【讨论】:

      【解决方案3】:

      问:在函数中使用 malloc() 的最佳方式是什么?

      答:如果你真的想在函数内部分配内存(就像现在一样),你必须释放这个函数外部的内存(也许使用其他补充函数)。有时人们会为这些函数使用特殊名称(例如 decrypt_ma() 而不是 decrypt())来记住内存分配的事实。

      问:如果我使用第 4 种方式,我是否必须在分配返回的指针之前对该变量进行 malloc() ?

      答:如果你在调用 decrypt() 之前分配内存,decrypt() 根本不应该返回指针(你将使用 p 进行所有操作,而不是 const 在主体函数)。

      【讨论】:

        【解决方案4】:

        一个简单的替代方法是就地修改字符串:

        void decrypt(char *p, int key) {
            for (; *p; p++) {
                if (*p >= 'A' && *p <= 'Z') {
                    if (key <= *p - 'A')
                        *p -= key;
                    else
                        *p += ('Z' - 'A' + 1) - key;
                } else
                if (*p >= 'a' && *p <= 'z') {
                    if (key <= *p - 'a')
                        *p -= key;
                    else
                        *p += ('Z' - 'A' + 1) - key;
                }
            }
        }
        

        请注意,您可以使用 256 字节数组编写更简单、更高效的实现。

        【讨论】:

        • 但是当我在数组内编辑指针时,它不会也在数组外被编辑,因为我正在使用char数组的地址吗?
        猜你喜欢
        • 1970-01-01
        • 2019-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-05
        • 2017-10-03
        • 2021-01-09
        相关资源
        最近更新 更多