Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 2 của 3 Đầu tiênĐầu tiên 123 CuốiCuối
Kết quả 11 đến 20 của 21
  1. #11
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    thêm chữ static trước mảng là OK...

    Mã:
    static char pm[100];
    Còn về phần Code 1 của bạn... tuy là chạy đúng nhưng bạn bị leaking memory... mấy cái con trỏ đó... cần phải delete.....

  2. #12
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mã:
    #include<malloc.h>
    #include<stdio.h>
    #include<conio.h>
    main()
    {
    	int *p;
    	p = (int *)malloc(sizeof(int));// lần (1)
    	*p = 12;
    	p = (int *)malloc(sizeof(int));// lần (2)
    	*p = 13;
    	getch();
    	
    }
    Vậy cho mình hỏi cấp phát bộ nhớ bằng malloc lần 1 và lần 2 như code trên là giống hay khác nhau vậy?Mình được biết hàm malloc trả về địa chỉ của một vùng nhớ và cho con trỏ trỏ đến vùng đó. Cấp phát lần 1 là cấp phát vùng nhớ 4 byte và trả về địa chỉ vùng nhớ đó rồi con trỏ p trỏ đến. Cấp phát lần 2 là cũng cấp phát vùng nhớ 4 byte và trả về địa chỉ vùng nhớ đó khác địa chỉ cấp phát lần 1 hay là giống địa chỉ lần 1 và cho con trỏ p trỏ đến vùng nhớ đó.

  3. #13
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ^ Thực ra mảng "tĩnh" ở đây để phân biệt với mảng "động" được tạo ra từ cấp phát động.
    "Tĩnh" hay "động" chính là kích thước vùng nhớ là hằng số hay thay đổi mỗi lần chạy.

  4. #14
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ^x2 ta nghĩ hiểu vậy cũng được rồi. Kỹ hơn nữa thì phải phân biệt chữ tĩnh và động...


    mảng nằm trên stack thì có kích cỡ cố định và được xác định khi biên dịch, còn mảng trên heap thì thay đổi kích cỡ được, được xác định khi chạy chương trình. Chữ tĩnh trong mảng tĩnh này là nói về kích cỡ của mảng là tĩnh/cố định, còn chữ động trong mảng động là nói về kích cỡ của mảng là dao động/ko cố định.

    ----------------

    phân biệt với biến "tĩnh" và biến "động", chữ tĩnh / động này là nói về địa chỉ của biến đó cố định / dao động.


    Biến local, hay biến nằm trong thân hàm, hay biến "động" thì có 2 loại 1 loại nằm trên stack 1 loại nằm trên heap. Biến từ malloc thì nằm trên heap, còn lại trên stack hết.

    Biến "tĩnh" có 2 loại: 1 là global, tức là ko nằm trong thân hàm, 2 là biến nằm trong thân hàm/lớp/v.v.. nhưng có keyword static.

    "tĩnh" ở đây là khai báo 1 lần và tồn tại đến hết chương trình, ko xóa bỏ/giải phóng khi chương trình đang chạy được. "động" là xuất hiện/biến mất liên tục. Vì xuất hiện/biến mất liên tục nên có địa chỉ ko cố định. Biến được đẩy lên stack thì tự động giải phóng, còn biến được đẩy lên heap (malloc) thì ko tự động giải phóng.

    Vd:
    void f() { int a[10]; } thì a là biến "động" nằm trên stack. Mỗi lần gọi f() thì a lại được đẩy lên stack rồi lấy khỏi stack. Tùy vào stack vơi hay đầy mà địa chỉ của a khác nhau.

    void f() { static int a[10]; } thì a là biến "tĩnh" nằm trên vùng bss. a được đẩy lên vùng bss khi chương trình bắt đầu chạy. Mỗi lần gọi f() thì a vẫn là cái mảng trên bss đó, ko thay đổi. Khi kết thúc chương trình thì a mới được giải phóng (tự động)

    void f() { int* a = (int*)malloc(sizeof(int)*10); free(a); } thì a là biến "động" nằm trên stack, còn mảng mà a trỏ tới là biến "động" nằm trên heap.

    void f() { static int* a = NULL; a = (int*)malloc(sizeof(int)*10); free(a); } thì a là biến "tĩnh" nằm trên vùng data, còn mảng mà a trỏ tới là biến "động" nằm trên heap. Khi gọi f() nhiều lần thì địa chỉ của a ko đổi, nhưng địa chỉ mà a trỏ tới thì thay đổi.

    int a[10]; int main() {} thì a là biến "tĩnh" nằm trên vùng bss.

    int* a = (int*)malloc(sizeof(int)*10); int main() { free(a); } thì a là biến "tĩnh" nằm trên vùng data, còn mảng mà a trỏ tới là biến "động" nằm trên heap.

    char a[10] = "123456789"; int main() {} thì a và "123456789" là biến "tĩnh" nằm trên vùng data, cụ thể hơn nữa là cả 2 đều nằm trên vùng read-only. Ở đây a là mảng.

    const char* a = "123456789"; int main() {} thì a và "123456789" là biến "tĩnh" nằm trên vùng data, cụ thể hơn nữa là a nằm trên vùng read/write, còn "123456789" nằm trên vùng read-only. Ở đây a là con trỏ, ko phải là mảng.

    int main() { char* a = "123"; } thì a là biến "động" nằm trên stack, còn "123" là chuỗi nằm trên vùng code/text, là hằng số, ko thay đổi được. Nếu gán a[0] = '0'; thì sẽ gây lỗi vì cố tình chép đè lên vùng code chỉ để đọc.

    (vùng data/bss là chứa biến global/static, data thì chứa biến được khởi tạo sẵn, còn bss thì chứa biến ko được khởi tạo)
    (vùng text là vùng chứa các câu lệnh và một số hằng số)

  5. #15
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    char a[10] = "123456789"; int main() {} thì a và "123456789" là biến "tĩnh" nằm trên vùng data, cụ thể hơn nữa là cả 2 đều nằm trên vùng read-only. Ở đây a là mảng.
    câu này phải là cả 2 nằm trên vùng read-write mới đúng. Ta nhầm :">

  6. #16
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ^ Thực ra lúc này hai bên dấu = là một [IMG]images/smilies/biggrin.png[/IMG]

    Khi ghi char* a = "123456789" thì mới có hai.

  7. #17
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ờm, đáng phải thêm vậy nữa, viết vậy thì a là "12345678"

  8. #18
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    char a[4] = "abc";

    thì có 2 "abc"
    1 "abc" nằm trên vùng ko thay đổi được
    1 "abc" được sao chép vào vùng nhớ thay đổi được

  9. #19
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi INTP
    ^x2 ta nghĩ hiểu vậy cũng được rồi. Kỹ hơn nữa thì phải phân biệt chữ tĩnh và động...


    mảng nằm trên stack thì có kích cỡ cố định và được xác định khi biên dịch, còn mảng trên heap thì thay đổi kích cỡ được, được xác định khi chạy chương trình. Chữ tĩnh trong mảng tĩnh này là nói về kích cỡ của mảng là tĩnh/cố định, còn chữ động trong mảng động là nói về kích cỡ của mảng là dao động/ko cố định.

    ----------------

    phân biệt với biến "tĩnh" và biến "động", chữ tĩnh / động này là nói về địa chỉ của biến đó cố định / dao động.


    Biến local, hay biến nằm trong thân hàm, hay biến "động" thì có 2 loại 1 loại nằm trên stack 1 loại nằm trên heap. Biến từ malloc thì nằm trên heap, còn lại trên stack hết.

    Biến "tĩnh" có 2 loại: 1 là global, tức là ko nằm trong thân hàm, 2 là biến nằm trong thân hàm/lớp/v.v.. nhưng có keyword static.

    "tĩnh" ở đây là khai báo 1 lần và tồn tại đến hết chương trình, ko xóa bỏ/giải phóng khi chương trình đang chạy được. "động" là xuất hiện/biến mất liên tục. Vì xuất hiện/biến mất liên tục nên có địa chỉ ko cố định. Biến được đẩy lên stack thì tự động giải phóng, còn biến được đẩy lên heap (malloc) thì ko tự động giải phóng.

    Vd:
    void f() { int a[10]; } thì a là biến "động" nằm trên stack. Mỗi lần gọi f() thì a lại được đẩy lên stack rồi lấy khỏi stack. Tùy vào stack vơi hay đầy mà địa chỉ của a khác nhau.

    void f() { static int a[10]; } thì a là biến "tĩnh" nằm trên vùng bss. a được đẩy lên vùng bss khi chương trình bắt đầu chạy. Mỗi lần gọi f() thì a vẫn là cái mảng trên bss đó, ko thay đổi. Khi kết thúc chương trình thì a mới được giải phóng (tự động)

    void f() { int* a = (int*)malloc(sizeof(int)*10); free(a); } thì a là biến "động" nằm trên stack, còn mảng mà a trỏ tới là biến "động" nằm trên heap.

    void f() { static int* a = NULL; a = (int*)malloc(sizeof(int)*10); free(a); } thì a là biến "tĩnh" nằm trên vùng data, còn mảng mà a trỏ tới là biến "động" nằm trên heap. Khi gọi f() nhiều lần thì địa chỉ của a ko đổi, nhưng địa chỉ mà a trỏ tới thì thay đổi.

    int a[10]; int main() {} thì a là biến "tĩnh" nằm trên vùng bss.

    int* a = (int*)malloc(sizeof(int)*10); int main() { free(a); } thì a là biến "tĩnh" nằm trên vùng data, còn mảng mà a trỏ tới là biến "động" nằm trên heap.

    char a[10] = "123456789"; int main() {} thì a và "123456789" là biến "tĩnh" nằm trên vùng data, cụ thể hơn nữa là cả 2 đều nằm trên vùng read-only. Ở đây a là mảng.

    const char* a = "123456789"; int main() {} thì a và "123456789" là biến "tĩnh" nằm trên vùng data, cụ thể hơn nữa là a nằm trên vùng read/write, còn "123456789" nằm trên vùng read-only. Ở đây a là con trỏ, ko phải là mảng.

    int main() { char* a = "123"; } thì a là biến "động" nằm trên stack, còn "123" là chuỗi nằm trên vùng code/text, là hằng số, ko thay đổi được. Nếu gán a[0] = '0'; thì sẽ gây lỗi vì cố tình chép đè lên vùng code chỉ để đọc.

    (vùng data/bss là chứa biến global/static, data thì chứa biến được khởi tạo sẵn, còn bss thì chứa biến ko được khởi tạo)
    (vùng text là vùng chứa các câu lệnh và một số hằng số)
    Quá chi tiết luôn. Cảm ơn bạn nhiều [IMG]images/smilies/biggrin.png[/IMG]

  10. #20
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi prog10
    Mảng tĩnh thì đúng vậy.
    Mãng tĩnh có phải là được khai báo như thế này không;
    char A[100];
    Còn mảng động là cấp phát động cho con trỏ đúng không.
    char *a;
    a = (char*)malloc(100);
    Do lúc mình học thì giảng viên mình chỉ nói mảng là mảng, mà cấp phát động là cấp phát động chứ k có mảng tĩnh hay mảng động gì hết.
    Thông qua đây thì mình thấy bị hổng kiến thức quá nhiều rồi. huhu.

 

 
Trang 2 của 3 Đầu tiênĐầu tiên 123 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •