简短的回答:是的,这是可能的
龙回答:malloc(some_size)
分配some_size
空间,并返回一个指向分配块的开始(或NULL
失败时)的地址。在做ret = (char*)malloc(sizeof(char) * length);
ret时,指定内存块的指针指向内存块length
char
s(请注意,sizeof(char) == 1
因此您可以将其删除)。
内存是你的,直到你释放它,即使在函数返回后,所以,在执行完upperCase(...)
之后,该内存仍然属于你。唯一的问题是,指针ret
被分配在本地存储的(auto)
堆栈上,这意味着当它的作用域为“死”(在你的情况下 - upperCase(...)
函数的作用域),因此,你将不知道该内存的位置是但是由于您从函数返回ret
,它所保存的值(这是您分配的内存的地址)将传递到main
的ret
,这基本上意味着您很好。
我认为我应该强调的最后一件事是,返回局部变量始终完成。例如int increment_by_one(int x){int y = x + 1; return y;}
。这是一个非常简单的函数,返回当地的值int y
。由于返回的值是我们需要的全部值(即值为x+1
),因此值(值)存储在局部变量中是可以的。因为ret
里面upperCase
包含分配的地址,所以“die”结束后,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注:
- 无需铸造malloc的返回值,这意味着
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}
和这样
是的,你可以做到这一点。问题在于返回指向不存在的事物的指针,但是你的'malloc'继续存在,直到你释放它。另一种选择是将输出指针作为参数,这样内存管理留给调用者。 – Ryan
'sizeof(char)'的定义是1。 – melpomene
'toupper(s [i])'具有未定义的行为,如果s [i]'为负数。你应该把它转换成'unsigned char'。 – melpomene