Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 6 của 6
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    int *p =(int*)malloc(1) cấp phát 1 byte;*p=n kiểu int (4 bytes) chương trình vẫn chạy đúng.Vậy code sai hay đúng?

    Mã:
    #include<stdio.h>
    #include<conio.h>
    #include<malloc.h>
    
    void main()
    {
    	int *p,n=5;
    	p = (int *)malloc(1);
    	for(int i = 0;i<n;i++)
    	{
    		printf("Nhap phan tu thu %d: ",i+1);
    		scanf("%d",&p[i]);
    	}
    	for(int i = 0;i<n;i++)
    		printf("%d
    ",p[i]);
    	getch();
    }
    Không hiểu sao mình cấp phát cho con trỏ p 1 byte mà vẫn nhập được n phần tử vậy thì bộ nhớ đâu để con trỏ p chứa giá trị. Nhưng mình chạy thì chương trình vẫn đúng không xuất hiện lỗi gì hết.Mình thắc mắc là code có sai không dù chương trình vẫn chạy.
    Mã:
    #include<stdio.h>
    #include<conio.h>
    #include<malloc.h>
    
    void main()
    {
    	int *p,n=5;
    	p = (int *)malloc(1);
    	*p = n;
    	printf("%d",*p);
    	getch();
    }
    Mình cấp phát cho con trỏ p 1 byte rồi gán nó cho biến n kiểu int( 4 bytes) đâu đủ kích thước để chứa biến kiểu int vậy mà chương trình chạy vẫn đúng không xuất hiện lỗi.Mình thắc mắc là code có sai không dù chương trình vẫn chạy.
    Mã:
    #include<stdio.h>
    #include<conio.h>
    #include<malloc.h>
    
    void main()
    {
    	char *p;
    	p = (char *)malloc(1);
    	gets(p);
    	printf("%s",p);
    	getch();
    }
    Nhập 1 chuỗi ký tự "ngon ngu lap trinh c" thì chương trình vẫn in ra bình thường không báo lỗi. Trong khi đó mình chỉ cấp phát cho con trỏ p 1 byte và chuỗi ký tự là 21 byte( kể cả NULL). Vậy thì bộ nhớ đâu để con trỏ lưu chuỗi ký tự đó.
    __________________________
    Những gì mình học về con trỏ trên trường là ví dụ như muốn lưu 5 giá trị kiểu int thì ta cấp phát như sau:
    p = (int *)malloc(5*sizeof(int));
    hoặc 1 chuỗi ký tự gồm n ký tự:
    p = (int *)malloc(n + 1);
    Mong mọi người giúp mình gở rối. [IMG]images/smilies/biggrin.png[/IMG]
    P.s:Mình dùng visual studio 2010.

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    code sai.

    đường vắng thì đậu xe dưới lòng đường vẫn ổn. Tới khi xe đông thì gây tai nạn. Cái này cũng tương tự, cấp phát 1 byte lề đường để chứa 4 chiếc xe thì 3 chiếc xe kia nó nằm dưới lòng đường. Chưa gây tai nạn ko có nghĩa là đậu xe dưới lòng đường an toàn.

    Tương tự cho cái cấp phát chuỗi ko đủ bộ nhớ kia.

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi INTP
    code sai.

    đường vắng thì đậu xe dưới lòng đường vẫn ổn. Tới khi xe đông thì gây tai nạn. Cái này cũng tương tự, cấp phát 1 byte lề đường để chứa 4 chiếc xe thì 3 chiếc xe kia nó nằm dưới lòng đường. Chưa gây tai nạn ko có nghĩa là đậu xe dưới lòng đường an toàn.

    Tương tự cho cái cấp phát chuỗi ko đủ bộ nhớ kia.
    Bạn giải thích thật dể hiểu. Mình cảm ơn nhiều [IMG]images/smilies/online.gif[/IMG]

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi Moscow
    Khi có một chương trình thứ 2 nào đó đang dùng bộ nhớ từ sau địa chỉ của p[0] (tức là từ &p[1] trở đi) thì việc bạn ghi đè vào bộ nhớ này của chương trình thứ 2 này sẽ gây lỗi cho chương trình của bạn (và có thể gây lỗi cho chương trình thứ 2 này); như vậy việc làm của bạn thật sự là thiếu an toàn. Code chạy được không có nghĩa chương trình của bạn thực sự OK. Bạn nhận ra vấn đề đó và thắc mắc như vậy cũng là một tư duy sâu sắc về code trong khi nhiều bạn khác không tư duy nhận ra vấn đề này. Đối với việc sử dụng stack (ví dụ như kiểu char p[4] mà bạn lại đi ghi lên p[4] trở đi) thì bạn sẽ có thể ghi đè lên các variables trong cùng function, hoặc đôi khi sẽ ghi đè lên return value của function; những việc làm này sẽ làm chương trình của bạn bị chết; và đôi khi người ta sẽ khai thác lỗi này của bạn để điều khiển chương trình của bạn (bạn có thể tìm và hiểu về buffer overflow); lỗi tràn bộ đệm và đôi khi corrupt stack.
    Mình cảm ơn bạn đã giúp mình hiểu sâu hơn vấn đề mình thắc mắc và cũng cung cấp mình thêm nhiều kiến thức mới.

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Khi có một chương trình thứ 2 nào đó đang dùng bộ nhớ từ sau địa chỉ của p[0] (tức là từ &p[1] trở đi) thì việc bạn ghi đè vào bộ nhớ này của chương trình thứ 2 này sẽ gây lỗi cho chương trình của bạn (và có thể gây lỗi cho chương trình thứ 2 này); như vậy việc làm của bạn thật sự là thiếu an toàn. Code chạy được không có nghĩa chương trình của bạn thực sự OK. Bạn nhận ra vấn đề đó và thắc mắc như vậy cũng là một tư duy sâu sắc về code trong khi nhiều bạn khác không tư duy nhận ra vấn đề này. Đối với việc sử dụng stack (ví dụ như kiểu char p[4] mà bạn lại đi ghi lên p[4] trở đi) thì bạn sẽ có thể ghi đè lên các variables trong cùng function, hoặc đôi khi sẽ ghi đè lên return value của function; những việc làm này sẽ làm chương trình của bạn bị chết; và đôi khi người ta sẽ khai thác lỗi này của bạn để điều khiển chương trình của bạn (bạn có thể tìm và hiểu về buffer overflow); lỗi tràn bộ đệm và đôi khi corrupt stack.

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bàn #Moscow nói khá chính xác đấy. Nói vui tí là bạn thếm 1 lỗi "memory leak" do không giải phóng bộ nhớ nữa, tin tặc có thể tấn công lấy cắp nhiều thông tin lắm đấy [IMG]images/smilies/clap_grin.gif[/IMG]

 

 

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
  •