0
int main() {
    int i = 0, ARRAY_SIZE = 500000;
    char **char_array;  
    
    char_array = (char **)malloc(ARRAY_SIZE * sizeof(char*));
    //physical memory used before loop = M KB
    for (i = 0; i < ARRAY_SIZE; i++) {
        char_array[i] = (char *)malloc(16 * sizeof(char));
    }
    //physical memory usage after loop = M+19532 KB 
    return 0;
}

I have the above piece of code. I don't understand where the 19532 KB of memory use is coming from. In my machine (64 bit), sizeof(char*) should be 8 bytes. For row initialization of an array, how is memory used? I'm a beginner in C, so any help would be appreciated.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
A_001
  • 1
  • 3
  • Yes, you're correct. 500000 × 8 byte = 4 megabyte. How are you measuring memory? – lionkor Aug 30 '20 at 21:23
  • 1
    Typically there is a minimum allocation size, if you request a small chunk less than the minimum you get the minimum. – M.M Aug 30 '20 at 21:23

2 Answers2

4

Every call to malloc uses some additional "overhead" memory beyond the amount you actually request. The library needs some space to keep track of those blocks to know how to free them later, and it may round up the size of small allocations for alignment.

Your allocation of char_array itself needs 500000 * 8, about 4 megabytes of memory, and the overhead is probably negligible. So it looks like your 500000 allocations of 1 byte each are actually using about 32 bytes each. This wouldn't be too unusual; for instance, malloc might be rounding up the size to 16 bytes for alignment, and then needing an additional 16 bytes for bookkeeping (say, 8 bytes each for a size and a pointer to the next block to make a linked list).

Obviously, this is a very inefficient way to allocate space for 500000 characters. You should instead just create an array of 500000 char (not pointers) and index into it directly.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
0
  1. malloc is allowed to arrange and "align" the blocks of memory you allocate in really any way it wishes, and in practice there are both minimum allocation sizes and internal bookkeeping overhead for each block. Single-byte allocations (inside the loop you're allocating chars and not char *s) are uncommon because they're inefficient to do like this; in practice you're probably actually allocating (at least) 8 bytes plus the internal overhead, each.

  2. Whatever "physical memory" measure you're looking at does not map precisely to what you're looking for here. malloc generally takes pools of memory from the OS and then doles it out into the smaller allocated blocks (with internal overhead) that you see at the level of your program. I would not expect any kind of exact correspondence between bytes allocated by the user program via malloc, and what the OS reports about the process. Perhaps a directional correlation holding all else equal, but not something worth spending much time trying to deduce conclusions from.

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204