我很困惑。有什么区别:
char *someFunction(char *src) {
char str[strlen(src) + 1];
...
return str;
}
和
char *someFunction(char *src) {
char *str = (char*)malloc((strlen(src) + 1) * sizeof(char));
...
return str;
}
第一个是数组(char[]
),第二个是malloc
。
我在学校学到的是,如果我想在函数中创建一个新的字符串,我应该使用malloc
。但是,它也可以在函数中使用char[]
(如第一个)。
老师说我们必须使用"堆区域",如果必须动态分配东西。
我认为第一个带数组(char str[..]
)也是动态的,因为char[]
的大小在程序开始之前实际上并不知道(这是正确的理解!?)。这个由我的编译器工作没有任何问题。
请轻松解释其中的差异并告诉我一些必须使用malloc
以及我不需要使用它的情况。
答案 0 :(得分:3)
我认为第一个带数组(
char str[..]
)也是动态的,因为char[]
的大小在程序开始之前实际上并不知道(正确理解!?)
没有。您使用自c以来添加的c99的可变长度数组功能。这不是动态分配
一旦函数完成其执行str
将不再存在,返回指针将调用未定义的行为。
答案 1 :(得分:2)
区别很简单:
第一个使用C99语法在自动存储中分配VLA(通常是堆栈上的 )。此数组只能在函数调用期间使用,不能返回指向它的指针,当调用者使用此返回值时,它将导致未定义的行为。此版本不正确。
第二个从堆中分配一个数组,可以在函数调用结束之后使用,直到free
或realloc
显式释放它为止。这种类型的分配通常被称为 dynamic ,这个词在英语中有更广泛的含义,但在这种情况下却没有。
请注意,您应该以这种方式简化分配:
char *someFunction(char *src) {
char *str = malloc(strlen(src) + 1);
....
return str;
}
根据定义, sizeof(char)
为1
,在malloc
中投放C
的返回值通常是一个坏主意,尽管在C++
中有必要,但是其他分配方法无论如何都是C++
的首选。
请注意,您可以使用Posix函数malloc
获取由src
strdup(src)
分配的副本。
当在当前函数结束后使用内存时,应使用malloc
及其变体分配的内存。如果大小很重要,您还应该使用malloc
来避免因耗尽自动存储而调用未定义的行为。限制因系统而异,但在现代环境中,自动存储通常可以为所有当前函数调用处理至少一兆字节,超出我建议使用堆存储的范围。
答案 2 :(得分:1)
使用VLA(第一个示例)表示函数返回时数组将不再存在。如果调用者尝试使用函数的返回值,则会显示未定义的行为。 VLA仅保证与符合1999 C标准(或更高版本)的编译器一起使用。
使用malloc()
(第二个示例)意味着在函数返回时不会释放数组(除非您的代码也显式调用free()
)。因此调用者可以安全地使用该版本函数的返回值。代码将与所有C标准(从1989/1990到今天),甚至一些早期的编译器一样。
答案 3 :(得分:0)
char str[n]
声明大型数组,则可能超出堆栈的存储空间,这将导致段错误答案 4 :(得分:0)
当你声明一个像ckar [something]这样的变量时,它会保存在堆栈中而不是堆中。这不是动态分配。如果你想动态地分配memmory你应该使用malloc并且数组将保存在堆中