MỖI NGÀY MỘT CÁI MỚI ^^

Thực ra thì mới với mình nhưng với mọi người chắc chỉ là nhắc lại cho nhớ thui. keke

Cái này khá hay nhưng hôm nay mình mới để ý. [Nguồn]: http://stackoverflow.com/questions/2705329/address-of-array-vs-address-of-array0-c-language

1. POINTER

mallocbuff isn't an array, it's a pointer. It's stored completely separate from where malloc allocates.
This would give the results you expect (and as required):
int main(){
  char buf[1];
  printf("&buf     == %p\n", &buf);
  printf(" buf     == %p\n",  buf);  // 'buf' implicitly converted to pointer
  printf("&buf[0]  == %p\n", &buf[0]);

  char* mbuf = buf;
  printf(" mbuf    == %p\n",  mbuf);
  printf("&mbuf[0] == %p\n", &mbuf[0]);

  printf("\n&mbuf(%p) != &buf(%p)\n", &mbuf, &buf);

  return 0;
}
Output:

&buf     == 0x7fff5b200947
 buf     == 0x7fff5b200947
&buf[0]  == 0x7fff5b200947
 mbuf    == 0x7fff5b200947
&mbuf[0] == 0x7fff5b200947

&mbuf(0x7fff5b200948) != &buf(0x7fff5b200947)

2. Difference between istream::get(char&) and operator>> (char&)

The difference depends on when there is a whitespace character on the stream buffer.
Consider the input ' foo'
char c;
cin.get(c);
Will store ' ' in c
However
char c;
cin >> c;
Will skip the whitespace and store 'f' in c

Tóm lại:
- File >> ch; // Không read whilespace and a character EOF
- File.get(ch) // Không read a character EOF
- ch = File.get(ch) //read ALL

3. Declare and define


Nguồn: http://daynhauhoc.com/t/khac-nhau-giua-khai-bao-va-dinh-nghia/5894

Giải thích chung chung:

Khai báo: là giới thiệu sự tồn tại của
  • một biến với kiểu dữ liệu cụ thể
  • một hàm với cấu trúc trả về và tham số nhận vào
Định nghĩa: là trình bày rõ
  • kiểu dữ liệu và giá trị khởi tạo một biến và yêu cầu compiler cấp vùng nhớ cho biến này
  • cấu trúc và nội dung của một hàm (sẽ ví dụ sau)

Giải thích và ví dụ cho biến:

Khai báo biến:
Ta có thể viết như sau, bắt buộc phải có từ khóa extern thì mới gọi là khai báo.

int main()
{
    extern int cu_lac_gion_tan;
}
Vì từ khóa extern cho biết rằng biến này được định nghĩa ở chỗ khác. Có nghĩa compiler không cần phải cấp vùng nhớ cho biến này.
Định nghĩa biến:
Vậy trường hợp ta viết như thông thường hay làm

int main()
{
    int cau_lam_gioi_the = 3;
}
Thì đây là sự kết hợp giữa khai báo và định nghĩa. Ở đây mình có thể hiểu là, tôi khai báo một biến kiểu intcó tên là cau_lam_gioi_the và xin compiler cấp cho nó một vùng nhớ, cho vùng nhớ đó gía trị 3.
Nếu mình không gán gía trị cho biến cau_lam_gioi_the thì compiler sẽ không gán gía trị gì vào vùng nhớ đã tạo cho biến này. Khi đó mình sẽ có một gía trị rác tại vùng nhớ đó.

Giải thích và ví dụ cho hàm:

Hàm thì đơn giản hơn nhiều
Đây là một khai báo

bool daynhauhoc_good(int member_num, int member_iq);
Đây là một định nghĩa

bool daynhauhoc_good(int member_num, int member_iq) 
{
    // actually I don't care about the arguments lol
    return true;
}

Giải thích và ví dụ cho class:

Đây là một khai báo

class DayNhauHoc();
Đây là một định nghĩa

class DayNhauHoc()
{
    public:
        DayNhauHoc() {}
}


4. Stack and Heap

Nguồn: http://daynhauhoc.com/t/vung-nh-stack-trong-c/2517/2

Khi một chương trình được thực thì bộ nhớ nó được chia ra làm 4 phần:
1. Code segment hay text segment: Để lưu trữ code thực thi
2. Data segment được chia làm 2 phần nhỏ:
- Initialized data segment: chứa biến toàn cục (global), static và biến const
- Uninitialized data segment(BSS): chứa các biến như Initialized data segment nhưng chưa được khởi tạo
3. Heap: Chứa các vùng nhớ được cấp phát bởi malloc, calloc
4. Stack: chứa các biến cục bộ (local variables), các tham số khi gọi hàm (arguments), địa chỉ trả về để tiếp tục thực thi sau khi kết thúc hàm (return address)

Vùng nhớ dưới đây được tạo ra trong stack, vì vùng nhớ này sẽ được hủy khi ra khỏi scope của nó
int arrays[100];
Vùng nhớ dưới đây được tạo ra trong heap, vì vùng nhớ này sẽ không được hủy khi ra khỏi scope của nó. Có khả năng gây ra memory leak
int * arrays = (int *)malloc(100 * sizeof(int));

Hậu quả của việc thực thi chương trình dưới đây là gì:
void circle()
{
 circle();
}

void main()
{
 circle();
}
Bạn khai báo 1 con trỏ thì nó sẽ chiếm 4 bytes (32bit) hoặc 8 bytes (64bit) trên stack
Nhưng việc cấp phát vùng nhớ cho con trỏ thì vùng nhớ đó nằm trên Heap
VD:
int *ptr; 
\\ Trên stack sẽ chiếm 4 bytes cho con trỏ này đối với platform 32bit

ptr = malloc(4 * sizeof(int));
 \\ Một vùng nhớ 16 bytes sẽ được cấp phát trên Heap và ptr sẽ trỏ đến vùng nhớ này


Hoặc có thể xem ví dụ này:

void foo()
{
    int DayNhauHoc; // stack
    int * pointer; // stack
    pointer = &DayNhauHoc; // trỏ tới stack
    
    int * dynamic_allocate; // stack
    dynamic_allocate = (int*)malloc(sizeof(int)); // trỏ tới heap
}
Cụ thể các biến được tạo ra trong hàm trên đều được tạo ra trên stack, vùng nhớ mà biến pointer trỏ tới cũng nằm trên stack.
Riêng có vùng nhớ mà biến dynamic_allocate trỏ tới là nằm trên heap. Bời vì vùng nhớ đó được cấp phát động.












Share on Google Plus

About Unknown

Phan Quang nguyen
    Blogger Comment
    Facebook Comment

0 nhận xét:

Đăng nhận xét