Thread: Confused about malloc and arrays

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    31

    Confused about malloc and arrays

    Hello,

    I just discovered something that left me wondering what I had actually understood about dynamic allocation of memory. Let's say I have the following trivial example:

    Code:
    int **array, i, j, nrows=10, ncolumns=20;
    
    array = malloc ( nrows * sizeof(int *) );
    for ( i = 0; i < nrows; i++ ) array[i] = malloc ( ncolumns * sizeof(int) );
      
    for ( i = 0; i < nrows; i++ )
    {
         for ( j = 0; j < ncolumns;  j++ ) 
         {
                array[i][j] = i*j;
                printf("%d %d %d\n",i,j,array[i][j]);
          }
    }
    This, of course, compiles and runs as expected.

    If I now change the last part to

    Code:
    for ( i = 0; i < nrows+1; i++ )
    {
         for ( j = 0; j < ncolumns; j++ ) 
         {
                array[i][j] = i*j;
                printf("%d %d %d\n",i,j,array[i][j]);
          }
    }
    I get a bus error when I run it, at the expected place (i=nrows+1). Good (I think?)

    If instead I do

    Code:
    for ( i = 0; i < nrows; i++ )
    {
         for ( j = 0; j < ncolumns+1; j++ ) 
         {
                array[i][j] = i*j;
                printf("%d %d %d\n",i,j,array[i][j]);
          }
    }
    The code compiles and runs happily. Indeed, I can go up to 10000*ncolumns or so, and the thing does not complain?!?!?!?!? (after some big number there is a segmentation fault)

    What am I actually doing with malloc? I am using gcc on OSX (Leopard)

    Thanks for any enlightenment,

    mc61

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I believe what you are seeing is undefined behaviour. The nasty thing is that appearing to work is one acceptable behaviour.

    If you step over the array bounds anything can happen.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The reason you don't get a "bus error" or similar when going "a little bit" outside your array is simply that the granularity for the memory management is not small enough to catch the fault. In most processor architectures, the page-size is 4KB, so that's the smallest size that an allocation will "fault at".

    Since, in your second example, you are only going 4 bytes "over the edge", you may not go over a 4KB limit, so the application doesn't get "faulted". You may, depending on how lucky you are, find that you've overwritten the admin structures of the heap, meaning that when you later on free your memory, the application crashes.

    If you were using x86 in protected & segmented mode, it would be possible to make allocations up to 1MB with 1 byte granularity, and that would give a fault immediately you got over the edge of the memory. Unfortunately, I'm not aware of any "available" OS that uses segmented mode in 32-bit memory model.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Jan 2008
    Posts
    69
    Quote Originally Posted by matsp View Post
    If you were using x86 in protected & segmented mode
    Forgive my ignorance, but what is protected/segmented mode?

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    x86 has several modes:
    1. Real-mode - what original DOS uses. Uses segments, but segments are "unprotected".
    2. Protected mode. Segments are "protected", meaning that a segment has a "limit" above which the processor can not write.
    This has several sub-modes:
    - 16-bit. Must use segments to get above 64KB memory limits. Segment size limit is max 64KB/
    - 32-bit. Segements can be used, limit can be 4GB. Most often used in Flat Memory model, where segments are set to 4GB limit.
    - 64-bit. Segments and limits are ignored [but still present].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Note: you can use tools like Valgrind (Linux-only) etc to catch out-of-bounds access of dynamically allocated memory. You don't get page faults, but you can still catch almost all errors. (Valgrind can theoretically catch all errors, which is why I like to use it -- the only trouble is, it really slows down your program when you use it. Not in the finished product, just during testing.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structures, arrays, pointers, malloc.
    By omnificient in forum C Programming
    Replies: 9
    Last Post: 02-29-2008, 12:05 PM
  2. Large arrays, malloc, and strcmp
    By k2712 in forum C Programming
    Replies: 1
    Last Post: 09-24-2007, 08:22 PM
  3. malloc for structs and arrays
    By rkooij in forum C Programming
    Replies: 15
    Last Post: 05-04-2006, 07:38 AM
  4. malloc ing array's or structures
    By Markallen85 in forum C Programming
    Replies: 4
    Last Post: 02-03-2003, 01:23 PM
  5. arrays with malloc
    By loobian in forum C Programming
    Replies: 3
    Last Post: 10-15-2001, 01:25 PM