cho mình hỏi đoạn code trên thì "hello" nằm trong stack?C++ Code:
nếu đúng thì cho mình hỏi tiếp
khi thực hiện phép gán cho g thì '10' ở đây có được allocate trong stack không?C++ Code:
int g =10;
ở đây thì arr[10] được allocate 40 bytes kiểu int trong stack. vậy còn pointer arr thì sao?C++ Code:
int arr[10];
có phải là nó còn allocate them 4 byte cho con trỏ arr nữa?
many thanks
Chuỗi "hello" không nằm trong stack. Những chuỗi kiểu như "hello" gọi là string literals, và các string literals này sẽ được để ở một vùng nhớ riêng. Vùng nhớ này thường là read-only, và nếu truy cập vào đó để thay đổi nội dung thì sẽ có lỗi runtime. Mình nhớ không nhầm thì trong C standard có nói rõ là sẽ có "undefined behavior". Do đó, không nên viết đoạn code
Một trong những lý do để mà string literals được đưa vào vùng nhớ riêng là để tiết kiệm bộ nhớ. Ví dụ bạn có thể có đoạn code:C Code:
char *p = "hello"; p[0] = 'H';
Rất có thể sẽ chỉ có một string literal "hello" ở trong bộ nhớ (nhưng việc có 1 hay nhiều hơn 1 thì tùy thuộc vào trình biên dịch).C Code:
char *s = "hello"; char a[] = "hello";
Chắc chắn g sẽ được cấp phát, nhưng nếu g được khai báo bên ngoài tất cả các hàm thì g sẽ được cấp phát trong phần .data (với Linux). Chú ý là nếu chỉ khai báo
như biến toàn cục, thì g sẽ được cấp phát ở phần .bss và sẽ được khởi tạo giá trị 0 (được đảm bảo bởi C standard).C Code:
int g;
Ngược lại nếu đó là khai báo trong một hàm, thì g sẽ được cấp phát trên stack.
Giá trị 10 sẽ không được cấp phát (trong cả trường hợp toàn cục và cục bộ), mà sẽ được chuyển thẳng vào trong mã máy được dịch ra (ít nhất là mã cho Intel vì nó cho phép "operand" của một lệnh có thể là một hằng).
Như ở trên, tùy theo arr được khai báo là biến toàn cục hay cục bộ mà arr sẽ được cấp phát ở phần .data hay là trên stack. Lưu ý là bộ nhớ cấp phát cho arr là 10 * sizeof(int). Trong đa phần các trường hợp, sẽ là 40, nhưng không nhất thiết.
Sẽ không có "pointer ar", không có bộ nhớ cấp phát cho "pointer arr". Trước hết là ví dụ đơn giản với đoạn lệnh
Biến g được cấp phát một vùng bộ nhớ kích thước sizeof(int). Biến g thực chất là để thuận tiện cho việc gọi đến vùng nhớ được cấp phát cho g.C Code:
int g = 10;
Quay trở lại câu hỏi của bạn. Chỉ có một vùng nhớ được cấp phát cho arr, tương tự như chỉ có một vùng nhớ cấp phát cho biến g. Nhưng với câu lệnh cout << *arr << endl; trình biên dịch sẽ chuyển arr thành kiểu con trỏ int và mang giá trị là vùng nhớ được cấp phát cho arr. Do đó câu lệnh sẽ in ra giá trị arr[0].
Không nên nhầm lẫn giữa con trỏ và mảng. Xem thêm ở đây: http://diendan.congdongcviet.com/showthread.php?p=630469#post630469