01/10/2018, 16:54

Biến được lưu trữ trong bộ nhớ thế nào?

em vừa đọc 1 bài trên kipalog thấy có đoạn này em thấy vô lý ạ
link : https://kipalog.com/posts/Pass-by-reference-va-pass-by-value#

trong đó có đoạn thế này :

 var a = {item: [1, 2]}

 function test(b) {
     console.log(a === b)   // true
     var b = {item: [1, 2]}
     console.log(a === b)   // false
 }

 test(a)

chổ giá trị của biến trong stack lúc này em nghĩ nó là 1 address chứ không phải là {item:[1,2]}
thứ 2 nữa là nếu trong java thì khi khởi tạo vùng nhớ cho kiểu dữ liệu reference thì sẽ khởi tạo trên heap chứ ko phải trên stack đúng ko? em nghĩ javascript cũng tương tự chứ ạ

Trần Hoàn viết 19:07 ngày 01/10/2018

Địa chỉ ở trên stack
Đối tượng ở trên heap

Có lẽ bài viết dùng từ không đúng, nhưng bạn hiểu là được mà

Madafaker viết 18:56 ngày 01/10/2018

theo như lý thuyết trong blog này thì sẽ có 1 symbol table lưu tên biến và địa chỉ của vùng nhớ trên stack , nhưng đó là trong trường hợp biến đó được khai báo và khởi tạo vậy nếu biến đó chỉ được khai báo nhưng không khởi tạo thì value trong symbol table sẽ lưu cái gì ??
theo suy nghĩ của riêng em đối với java >>

  1. nếu biến thuộc kiểu dữ liệu tham chiếu thì lúc này nó sẽ trỏ về NULL
  2. nếu biến thuộc kiểu dữ liệu nguyên thủy lúc này sẽ có 2 trường hợp
  3. nếu biến nằm trong method >> trình biên dịch sẽ bắt buộc phải khởi tạo giá trị cho biến
  4. nếu biến nằm ngoài method >> sẽ tự động gán giá trị mặc định cho biến ( int = 0 , boolean = false)

còn đối với c thì sao ?? c không có đối tượng vậy khi chỉ khai báo biến mà không khởi tạo giá trị ban đầu thì nó sẽ trỏ đến địa chỉ nào ??

viết 19:08 ngày 01/10/2018

với C thì nếu khai báo biến mà ko khởi tạo thì trên stack nó có giá trị gì thì biến sẽ có giá trị đó. Hiểu nôm na là bạn thuê 1 căn nhà mới, ông chủ nhà ko dọn dẹp đồ của người thuê cũ, bạn cũng ko dọn dẹp (ko khởi tạo) thì nhà thuê của bạn chứa rác thôi. Nếu dữ liệu rác này là con trỏ thì nó chứa địa chỉ ngẫu nhiên, trỏ tới địa điểm asdfasdfsw nào đó, ai mà biết @_@

Madafaker viết 18:57 ngày 01/10/2018

vd mình khai báo : int x ;
thì nó sẽ cấp phát 1 vùng nhớ tương đương ( int ) trên stack và value của vùng nhớ này sẽ là 1 giá trị lung tung nào đó à …

Madafaker viết 19:01 ngày 01/10/2018

à em có 1 thắc mắc nữa:

ClassA object1 = null ;
ClassA object2 ;

(giả sử nếu trong c# hoặc java cho phép ta lấy được địa chỉ của biến giống trong C )

nếu mình sử dụng toán tử & để lấy địa chỉ của object1 ( &object1 ) thì nó sẽ trả về địa chỉ hay trả về null ?? ( nếu theo lý thuyết trên thì nó sẽ cấp cho object1 1 vùng nhớ nhưng value của vùng nhớ này là null )

nếu mình sử dụng toán tử & để lấy địa chỉ của object2 ( &object2 ) thì nó sẽ trả về địa chỉ hay trả về null ??

viết 19:09 ngày 01/10/2018

vd mình khai báo : int x ;
thì nó sẽ cấp phát 1 vùng nhớ tương đương ( int ) trên stack và value của vùng nhớ này sẽ là 1 giá trị lung tung nào đó à …

đúng, nếu khai báo int x; trong 1 cái hàm nào đó. Còn nếu khai báo biến toàn cục thì nó sẽ được khởi tạo với giá trị là 0. Tất cả biến toàn cục đều được gán 0 hết nếu ko được khởi tạo.

sở dĩ biến toàn cục được gán 0 còn biến cục bộ ko được gán 0 vì khi khởi động chương trình, biến toàn cục được load lên memory thì chỉ load 1 lần, nên sẵn tiện gán 0 luôn, ko ảnh hưởng tới thời gian chạy chương trình. Còn hàm số chứa biến cục bộ thì có thể được gọi tỷ tỷ lần, nếu mỗi lần gọi gán 0 thì vô tình làm chậm chương trình nên trình biên dịch nó sẽ bỏ qua ko gán 0 cho các biến cục bộ, nếu các biến cục bộ này ko được khởi tạo.

(giả sử nếu trong c# hoặc java cho phép ta lấy được địa chỉ của biến giống trong C )

có thể hiểu biến trong Java khi ko phải là kiểu nguyên thủy mà refer tới 1 object nào đó là con trỏ trong C. Vậy có thể viết lại code “tương đương” trong C là:

struct ClassA * object1 = NULL;
struct ClassA * object2; //ko biết trỏ tới đâu

&object1 sẽ trả về địa chỉ của con trỏ object1 nằm trên stack, không phải là địa chỉ mà object1 trỏ tới (NULL). Tương tự &object2 trả về địa chỉ của con trỏ object2 nằm trên stack, ko pải là địa chỉ “ma” mà object2 trỏ tới.

Trần Hoàn viết 18:55 ngày 01/10/2018
ClassA A1 = NULL:// A1 == null, A1.initialized flag = true;
ClassA A2;// A2 == null, A2.initialized flag = false;

Bạn có thể hiểu là biến trong java nó chỉ là reference thôi, kể cả kiểu nguyên thuỷ nó cũng không phải kiểu nguyên thuỷ thực sự, vì nó vẫn cần máy ảo để chạy.

Bọn nó không hẳn là con trỏ. Vì con trỏ cũng là một kiểu dữ liệu (int* chẳng hạn), còn biến trong Java hay C# hay JavaScript nó chỉ là một cái tên.

PHP thì mình ruồng bỏ từ ngày mới phải học, Ruby không học nên không dám nói tới.

Madafaker viết 19:03 ngày 01/10/2018

thanks anh đúng với những gì em nghĩ …

Madafaker viết 18:59 ngày 01/10/2018

ok em hiểu rồi thực sự thì do cái blog trên nó lấy tư tưởng từ C sang nên mấy cái ví dụ của nó không đúng cho lắm vì khi em debug trên java và c# thì thấy khác với trong ví dụ…@@

Bài liên quan
0