【问题标题】:Stack usage in C vs in JavaC 与 Java 中的堆栈使用情况
【发布时间】:2019-12-10 23:35:42
【问题描述】:

我正在学习堆栈的用法,我注意到它们在 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 中却如此?

【问题讨论】:

  • 1.语言根本不同。 2. Java 通过垃圾收集使用内存管理,而 C 没有。 3. 你的 C 代码调用了未定义的行为; Java 已定义行为。
  • 您的 Java 和 C 函数不等价。 C 变体正在使用输入来填充本地数组。 Java 变体只是简单地为字符串赋值。 char *name = "A name"; 更接近于您的 Java 函数,并且可以正常工作。
  • 最好将 C++ (std::string name) 与 Java 进行比较,因为它们都具有 C 完全缺乏的内存管理功能。这主要是因为 C 被设计为低级的,而 C++ 和 Java 具有建立在低级原语上的重要而深入的抽象层。
  • 堆栈在 Java 中被破坏。只是将返回的函数局部变量放在堆上,在那里它们将被保留,直到不再有任何引用,然后被垃圾回收。这是语言的一部分。
  • Java 几乎不使用堆栈。所有对象都在堆上静默分配。 C 代码不起作用的原因不是因为某些“破坏者”,而是因为您向调用者返回了一个无效的指针。

标签: java c stack


【解决方案1】:

在 Java 中,局部变量的内存不是在堆栈上分配的……只有引用放在堆栈上。对象本身放在堆上。

【讨论】:

  • 局部变量在栈上分配;它是对字符串对象的引用。
【解决方案2】:

在 Java 中,new Stringheap 而不是 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】:

    您正在返回一个指向局部变量的指针,一旦函数返回,该指针就会超出范围。然后取消引用该指针是 C 中未定义的行为。

    在 Java 中,String 是一个托管对象,需要进行垃圾回收。因此它将被保留,直到不再存在对它的引用。

    相比之下,C 没有托管对象,也没有垃圾收集器。您必须自己照顾“对象”的生命周期。

    【讨论】:

      【解决方案4】:

      在 Java 中,字符串分配在堆上,而不是堆栈上,并且为每个字符串分配新内存。在 Java 中实际上不可能破坏字符串,因为 Java 的字符串是不可变的。

      【讨论】:

        猜你喜欢
        • 2013-07-06
        • 2021-09-03
        • 2015-04-13
        • 2012-03-14
        • 2011-12-15
        • 2012-05-09
        • 1970-01-01
        • 2013-08-18
        • 2012-01-18
        相关资源
        最近更新 更多