函数内部 malloc 的 C 用法

Posted

技术标签:

【中文标题】函数内部 malloc 的 C 用法【英文标题】:C usage of malloc inside a function 【发布时间】: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 个选项:

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

这是选项 #4 的代码:

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

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

我的问题是:

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

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

【问题讨论】:

【参考方案1】:

应该是:

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

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

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

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

【讨论】:

计划 3 很好,因为您可以选择是否应该在堆栈或堆上分配 - 功能更灵活。 另外,你应该释放返回的指针并不是很明显——这很容易忘记。其他答案提到,最好附加一些后缀,如 _ma 在 win api 选项 3 中很常见,例如docs.microsoft.com/en-us/windows/win32/api/iphlpapi/… _CrtDumpMemoryLeaks 很有帮助 :) docs.microsoft.com/en-us/visualstudio/debugger/… 和 ***.com/questions/2153776/… @FrancescoBoccardo free(var) 释放内存,因为函数会执行 return tmp;【参考方案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数组的地址吗?

以上是关于函数内部 malloc 的 C 用法的主要内容,如果未能解决你的问题,请参考以下文章

c语言malloc函数

malloc与free函数用法

C语言中的malloc函数的使用?

C语言中free函数的用法

C语言中动态内存分配函数的用法及作用?(比如malloc,calloc,realloc等)

malloc函数实现的功能是啥?