我正在学习栈的用法,我注意到在C和Java中它们的使用方式不同,或者显然如此。例如,下面用C编写的代码将无法工作,因为它将破坏“名称”
char* getName(){
char name[32];
scanf( "%s",name);
return name;
}
int main (int argc, char *argv[]){
char *myName = getName();
printf("%s", myName);
}
但是,如果我用Java编写类似的代码,则效果很好:
public static String getName(){
String name = "A name";
return name ;
}
static void main(String[] args){
String name = getName();
System.out.print(name);
}
我想知道为什么。为什么堆栈在Java中不会使容器崩溃,而在C语言中会导致容器崩溃?
答案 0 :(得分:2)
在Java中,局部变量的内存未分配在堆栈上……仅将引用放置在堆栈上。对象本身放在堆上。
答案 1 :(得分:1)
您正在返回一个指向局部变量的指针,该局部变量一旦函数返回就超出范围。然后,取消引用该指针是C中的未定义行为。
在Java中,String
是一个托管对象,并受到垃圾回收的影响。因此它将一直保留,直到不再存在对其的引用为止。
C没有托管对象,也没有垃圾收集器。您必须自己照顾“对象”的寿命。
答案 2 :(得分:1)
在Java中,new String
在堆而不是 stack 上创建一个对象。因此,Java中的new
与C语言中的malloc
类似。
相当于
// Java
public static String getName() {
String name = "A name";
return name;
}
将会
// C
static String *getName() {
String *name = String_new("A name");
return name;
}
其中String
“类”的定义如下:
typedef struct {
char *buf;
} String;
String *String_new(const char* src) {
String *string = malloc(sizeof(String));
string->buf = strdup(src);
return string;
}
void String_free(String *this) {
free(this->buf);
free(this);
}
Java中没有等效于C的char name[32];
(元素在堆栈中的数组)。
答案 3 :(得分:0)
在Java中,字符串是在堆上分配的,而不是堆栈上的,并且为每个字符串分配新的内存。实际上,不可能用Java破坏字符串,因为Java的字符串是不可变的。