#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函数,是否可以返回局部变量来终止函数并释放内存?我对仍有记忆的范围知之甚少。
答案 0 :(得分:4)
简短回答:是的,可能
长答案:malloc(some_size)
分配some_size
空格并返回指向已分配块的开头地址的指针(或失败时为NULL
)。在执行ret = (char*)malloc(sizeof(char) * length);
时,会为ret分配指向length
char
的内存块的指针(请注意sizeof(char) == 1
,以便将其删除)。
即使在函数返回后,内存也是你的,直到你释放它为止,因此,在upperCase(...)
执行结束后,该内存仍然属于你。唯一的问题是,指针ret
是在具有(auto)
本地存储的堆栈上分配的,这意味着它将&#34; die&#34; 范围(在您的情况下 - upperCase(...)
函数的范围),因此,您将无法知道该内存的位置,但是,因为您从ret
返回main
函数,它所拥有的值(这是你分配的内存的地址)将传递给ret
int increment_by_one(int x){int y = x + 1; return y;}
,这基本上意味着你很高兴。
我认为我应该强调的最后一件事是,返回局部变量一直在进行。例如int y
。这是一个非常简单的函数,它返回本地x+1
的值。由于返回的值是我们所需要的(即ret
的值),因此它(值)存储在局部变量中是可以的。同样(有点)适用于您的情况 - 因为upperCase
内的upperCase
包含已分配的地址,因此&#34; die&#34; <{1}}结束后的,因为传递的值(地址)被传递。
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注:
ret = (char*)malloc(sizeof(char) * length);
应为ret = malloc(sizeof(char) * length);
sizeof(char)
,因为它1
,这意味着您可以将其进一步缩短为ret = malloc(length);
malloc
可能会失败。在这种情况下,它会返回NULL
,因此在每ret = malloc(...);
后,您应该检查if(!ret){// handle error}
或if(ret != NULL){// do something}
等值答案 1 :(得分:2)
是的,你可以。
malloc
内存在堆上,因此在upperCase
结束时不会释放。
但是变量char *ret
在堆栈中,当upperCase
结束时它将弹出。但ret
中upperCase()
的值已通过ret = upperCase(input)
中的main()
复制。也就是说,您仍然可以获得已分配内存的地址,该内存仍在堆上。完成使用此内存后,您可以调用free(ret)
。
检查What and where are the stack and heap?以获取有关堆栈和放大器的详细信息。堆。