我可以对局部变量使用 "malloc" 来返回局部变量吗?


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char * upperCase(const char* s)
{
char * ret = NULL;
size_t length = strlen(s) + 1;
ret = (char*)malloc(sizeof(char) * length);
for (size_t i = 0; i < length; i++) {
ret[i] = toupper(s[i]);
}
return ret;
}
int main()
{
char* ret = NULL;
char* input = "HelloWorld";
ret = upperCase(input);
printf("value = %s", ret);
free(ret);
}

上面的代码将一个字符串作为参数并复制该字符串。它 然后将复制字符串的每个元素转换为大写和 返回它。

编译器 = GCC 6.2

如果使用 malloc 函数,是否可以返回局部变量来终止函数并释放内存?我对仍有记忆的范围没有足够的了解。

简短回答:是的,这是可能的

长答案malloc(some_size)分配some_size空间并返回指向已分配块开头地址的指针(或失败时NULL(。执行ret = (char*)malloc(sizeof(char) * length);ret 时分配了指向lengthchars 内存块的指针(请注意,sizeof(char) == 1,以便您可以删除它(。

内存是你的,直到你释放它,即使在函数返回之后,所以,在upperCase(...)执行结束后,内存仍然属于你。唯一的问题是,指针ret被分配给具有(auto)本地存储的堆栈上,这意味着当它是作用域时(在您的情况下 -upperCase(...)函数的作用域(时它将"死亡">,因此,您将不知道该内存在哪里,但是由于您从函数返回ret,它持有的值(即您分配的内存的地址(将传递给mainret, 这基本上意味着你可以开始了。

我认为我应该强调的最后一件事是,返回局部变量一直在进行。例如int increment_by_one(int x){int y = x + 1; return y;}.这是一个非常简单的函数,返回本地int y的值。由于返回的值是我们所需要的(即x+1的值(,因此它(值(存储在局部变量中是可以的。同样(有点(适用于您的情况 - 因为upperCase内部ret保存分配的地址,因此它可以在upperCase结束后"死亡">,因为它持有的值(地址(被传递。

char * upperCase(const char* s)
{
char * ret = NULL;                             // local variable -> will die after upperCase ends
size_t length = strlen(s) + 1;                 // local variable -> will die after upperCase ends
ret = (char*)malloc(sizeof(char) * length);    // ret assigned with address to memory
for (size_t i = 0; i < length; i++) {          // local variable -> will die after it's scope (the for loop) ends
ret[i] = toupper(s[i]);
}
return ret;                                     // said address is returned to main (local variable ret now dies peacefully after fulfilling its duty) 
}
int main()
{
char* ret = NULL;               // local variable -> will die after main ends
char* input = "HelloWorld";     // local variable -> will die after main ends
ret = upperCase(input);         // ret gets the address allocated in upperCase
printf("value = %s", ret);
free(ret);                      // address is freed
}

2 注意事项:

  1. 无需强制转换 malloc 返回值,这意味着应该ret = (char*)malloc(sizeof(char) * length);ret = malloc(sizeof(char) * length);
  2. 不需要sizeof(char),因为它是1,这意味着您可以将其进一步缩短为ret = malloc(length);
  3. malloc可能会失败。在这种情况下,它将返回NULL因此在每次ret = malloc(...);后,您应该检查if(!ret){// handle error}if(ret != NULL){// do something}等值

是的,你可以。

malloc内存位于堆上,因此upperCase结束时不会释放。

但是可变char *ret在堆栈上,upperCase结束时会弹出。但是upperCase()ret的值是通过main()中的ret = upperCase(input)复制的。也就是说,您仍然获得分配内存的地址,该地址仍在堆上。您可以在完成使用此内存后调用free(ret)

查看堆栈和堆

是什么以及在哪里?,了解有关堆栈和堆的详细信息。

最新更新