Từ 1 tới 10 trên tổng số 10 kết quả

Đề tài: Lỗi tràn số trong lập trình C????

  1. #1
    Ngày gia nhập
    10 2007
    Bài viết
    4

    Mặc định Lỗi tràn số trong lập trình C????

    Mình viết chương trình trên MVC2005 bằng ngôn ngữ C. Khi khai báo mảng 2 chiều kích thước 100x100(ma trận vuông) thì chương trình chạy bình thường, nhưng khi tăng kích thước lên 1000x1000 (thậm trí nhỏ hơn kích thước này) thì máy báo lỗi Stack overflow. Các bác có kinh nghiệm giúp mình xử lý với! Chân thành cảm ơn!
    NEVER GIVE UP! ! !

  2. #2
    Ngày gia nhập
    09 2006
    Bài viết
    711

    1000 * 1000 * 4 (vd là mãng integer) gần = 4MB, tràn stack là chắc chắn. Vào Project Options, chỉnh lại stack size hay dùng dynamic alloc memory (new, malloc)

  3. #3
    Ngày gia nhập
    10 2007
    Nơi ở
    HCMUNS
    Bài viết
    459

    Cậu này gan ghê, hồi đó tui chơi cái int [100][100] đã lo muốn chết :-ss. Cậu dám chơi tới 1000x1000 :-o. Cấp phát bộ nhớ động như anh TQN nói là oke đó

    @TQN: em chả bao giờ chỉnh cái size của stack cả ++
    Keep moving forward!

    ... Retired ...

  4. #4
    Ngày gia nhập
    10 2007
    Bài viết
    4

    Cảm ơn bác TQN nhé! em làm theo gợi ý của bác và đúng là chuơng trình đã làm việc với [1000000][1000000] lận, nhưng vài lần chạy thì có vấn đề. Em post đoạn code lên đây bác nào rỗi thì chạy thử giúp em nhé.
    @nhc1987: em chả gan gì đâu nhưng đang làm bài toán về mạng nơ ron cần cái ma trận to to nên liều đại thôi bác ạ!
    C Code:
    1. #include "stdafx.h"
    2. #include "stdio.h"
    3. #include"conio.h"
    4. #include "stdlib.h"
    5. #include "time.h"
    6. #include "windows.h"
    7. #include "malloc.h"
    8.  
    9.  
    10. double realrandom(int n)
    11. {
    12.    return (double) rand()/(double) RAND_MAX*n;
    13. }
    14.  
    15. int _tmain(int argc, _TCHAR* argv[])
    16. {
    17.     long i,j,s,n,a,b,N;
    18.    
    19.     double *J,f;
    20.    
    21.    
    22.     srand((unsigned)time( NULL )); //sinh sự ngẫu nhiên time(NULL)
    23.     printf ("vao gia tri max = ");
    24.     scanf ("%ld",&n);
    25.     printf("\nnhap so hang`(cot) cua ma tran N = ");
    26.     scanf("%ld",&N);
    27.     J=(double*)calloc(1000000*N*N,sizeof(double));
    28.     for (i=0;i<N;++i)
    29.         for (j=0;j<N;++j)
    30.         {
    31.             f = realrandom(n);
    32.             a= rand()%1000;          //cho a 1 con số ngẫu nhiên từ 0-999
    33.             b = a%2;
    34.             if(b == 1)  s = 1;
    35.             else   s = -1;
    36.             f = s*f;
    37.             *(J + N*i + j) = f;
    38.             printf("J[%ld][%ld] = %lf\n",i,j,*(J + N*i + j));
    39.         }
    40.     free(J);
    41.     getchar();
    42.     return 0;
    43. }
    NEVER GIVE UP! ! !

  5. #5
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Vài lần chạy có vấn đề ? Vấn đề gì ?
    Đọc code cậu tui thấy cậu chỉ truy xuất trong ma trận N x N, thì cấp làm gì cho lớn thế (x 1000000) ?
    Đã được chỉnh sửa lần cuối bởi TQN : 16-11-2007 lúc 02:28 PM.

  6. #6
    Ngày gia nhập
    06 2007
    Nơi ở
    một nơi xa xăm...
    Bài viết
    127

    Mặc định Lỗi tràn số trong lập trình C????

    Nên dùng cấp phát bộ nhớ động là tốt nhất

  7. #7
    Ngày gia nhập
    10 2007
    Bài viết
    4

    Trích dẫn Nguyên bản được gửi bởi TQN Xem bài viết
    Vài lần chạy có vấn đề ? Vấn đề gì ?
    Đọc code cậu tui thấy cậu chỉ truy xuất trong ma trận N x N, thì cấp làm gì cho lớn thế (x 1000000) ?
    Vấn đề đây các bác xem giúp em:
    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		memory-error.jpg
Lần xem:	7
Size:		57.4 KB
ID:		5329

    Trích dẫn Nguyên bản được gửi bởi Alviss Xem bài viết
    Nên dùng cấp phát bộ nhớ động là tốt nhất
    Bác có thể nói rõ hơn ko? mình mới voọc mà
    NEVER GIVE UP! ! !

  8. #8
    Ngày gia nhập
    10 2006
    Nơi ở
    In Your Bugs
    Bài viết
    823

    Có vấn đề là đúng rồi. Nó bị phân mảnh thôi . Này nhé khi cậu dùng calloc thì buộc nó phải tìm cho ra vùng nhớ LIÊN TIẾP để cấp phát cứ như thế sau hai 3 lần chạy thì bộ nhớ cậu bị phân mảnh hết, hay đúng hơn là bị băm nát hết. Thành thử SIZE thì lớn hơn lượng yêu cầu cần cấp phát, nhưng để tìm đúng lượng yêu cầu (Có thể gọi là quá đáng - vì dùng ko hết này) thì khó khăn do 2 cái từ Liên Tiếp nó gây nên.

    1000000*N*N
    Mô phật em chả hiểu anh dùng cái gì mà để dư khủng khiếp thế kia. Lãng phí quá đáng.

    Trường hợp này có thể dùng List. Nếu thấy cần.

  9. #9
    Ngày gia nhập
    10 2007
    Bài viết
    4

    Trích dẫn Nguyên bản được gửi bởi kidkid Xem bài viết
    Có vấn đề là đúng rồi. Nó bị phân mảnh thôi . Này nhé khi cậu dùng calloc thì buộc nó phải tìm cho ra vùng nhớ LIÊN TIẾP để cấp phát cứ như thế sau hai 3 lần chạy thì bộ nhớ cậu bị phân mảnh hết, hay đúng hơn là bị băm nát hết. Thành thử SIZE thì lớn hơn lượng yêu cầu cần cấp phát, nhưng để tìm đúng lượng yêu cầu (Có thể gọi là quá đáng - vì dùng ko hết này) thì khó khăn do 2 cái từ Liên Tiếp nó gây nên.


    Mô phật em chả hiểu anh dùng cái gì mà để dư khủng khiếp thế kia. Lãng phí quá đáng.

    Trường hợp này có thể dùng List. Nếu thấy cần.
    Hà hà bác giải thích có lý quá đi mất. Thế cho mình hỏi có cái lệnh nào gộp cái sự phân mảnh lại sau mỗi lần chạy chtrinh` như cái tiện ích defracment disk của Window ko nhỉ?!
    NEVER GIVE UP! ! !

  10. #10
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Memory allocate hơi bị lớn nên các hàm quản lý memory của VC++6 RTL không cấp được. Cậu đang build ở mode DEBUG, chuyển qua build ở mode Release để dùng trực tiếp HeapAlloc API của Windows, nhớ kiểm tra exception hay NULL pointer trả về cho biến J khi calloc.

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn