C与Java的堆栈使用情况

时间:2019-12-10 23:35:42

标签: java c stack

我正在学习栈的用法,我注意到在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语言中会导致容器崩溃?

4 个答案:

答案 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的字符串是不可变的。