Misunderstanding about how memory is created using malloc () / calloc ()

My concept for a way malloc()/calloc()

to create memory has always been that after the element is created, the address of the object remains the same. But a function that I often use to create an array of strings, and one that seems to have always worked well, recently led me to question my understanding, that is, object memory addresses can (and) be moved just by calling calloc/malloc

.

To illustrate, here is the function I used to create memory for an array of strings - char **

:

char ** CreateArrayOfStrings(char **a, int numWords, int maxWordLen)
{
    int i;
    a = calloc(numWords, sizeof(char *));   //create array of pointers
    if(!a) return a;                        //required caller to check for NULL
    for(i=0;i<numWords;i++)
    {
        a[i] = calloc(maxWordLen + 1, 1);   //create memory for each string 
    }
    return a;
}  

      

On my system (Win7, 32bit compile, ANSI C) Line:

a = calloc(numWords, sizeof(char *));   //create array of pointers  

      

Creates a block of contiguous memory, size for numWords char *

, in this case 7, which gives 28 bytes:

enter image description here

Memory scrolls from address 0x03260080 + 1C (0x0326009C)
Or:

a[0] is at 0x3200260080    
a[1] is at 0x3200260084    
a[2] is at 0x3200260088    
a[3] is at 0x320026008C
a[4] is at 0x3200260090    
a[5] is at 0x3200260094    
a[6] is at 0x3200260098    

      

Then I create memory for each line numWords

(7)

for(i=0;i<numWords;i++)
{
    a[i] = calloc(maxWordLen + 1, 1);   //maxWordLen == 5 in this example
}  

      

This leads to the following:

enter image description here

This indicates that the pointer memory areas a[1] - a[6]

have changed.

Can someone explain how / why this is happening in malloc()/calloc()

?

+3


source to share


3 answers


It looks like you are comparing apples to oranges:

  • When you print pointers a[i] is at ...

    , you are specifying the addresses of the elements inside the arraya

  • However, when you hover over the memory layout, you are showing the values ​​at these addresses, which are themselves pointers, so the whole picture looks confusing.

If you print the values ​​in a[i]

before assigning the results to them calloc

, you should get all zeros because it is calloc

NULL

deduced from memory. After the assignments, you see pointers to 6-byte blocks on each a[i]

, which makes sense.



To summarize, your initial understanding of what happens when you allocate memory with malloc

and calloc

is correct: after allocating a chunk of memory, its address * remains unchanged.

* On systems with virtual memory, I have to say "its virtual address".

+7


source


The memory of these addresses has not been changed. You create a 28-byte large block of space ( a

) and then for each item, dynamically allocating a second 6-byte block of space with its own address.

In other words, in item [1] (memory address 0x03260084

) the value is saved , there is a pointer to the memory address 0x32600D0

.



To check memory locations and values ​​on each of them, try the following:

for ( i = 0; i < 8; i++ )
{
    printf("a[%d] %p %p\n",i,&(a[i]),a[i]);
}

      

+3


source


When you call calloc(numWords, sizeof(char *))

, you are asking the operating system to allocate numWords

pointers of size `` 4 bytes on your system '', so the resulting block is 4 * numWords

bytes, and it returns refer to the first one. Now you can store the addresses of the pointers that will contain the actual data. The nth call calloc(maxWordLen + 1, 1)

will then return the address in a block of size maxWordLen

and store it in the memory location it points to a[n]

, which is just the address returned by the first call to calloc

plus n * sizeof(char *)

.

+1


source







All Articles