This is the malloc prototype()
void *malloc(size_t size);
And this is what the documentation in Portuguese says in Microsoft Docs about malloc()
:
size
Bytes to allocate
And about the value returned
malloc returns a void pointer to the allocated space or NULL if not
there is enough memory available. To return a pointer to
a different type of void , use a type conversion at the value of
return. The storage space pointed out by the returned value is
guaranteed to be subtly aligned for storage of any
object type with an alignment requirement equal to or less than
fundamental alignment. (In Visual C++, the fundamental alignment is the
alignment required for a double or 8 bytes. In the code you have
as target 64-bit platforms, it is 16 bytes. ) Use _aligned_malloc
to allocate storage to objects that have a requirement of
major alignment - for example, the types of SSE __m128 and __M256
types declared using __declspec(align( n )) where n is greater than 8.
If the size is 0, malloc will allocate a zero-length item in the heap
and will return a valid pointer for this item. Always check the
malloc return, even if the requested amount of memory is
little. Commentary The malloc function allocates a block of hair memory
less bytes of size . The block can be larger than the size in bytes
due to the space required for alignment information and
maintenance. malloc defines Errno as ENOMEM if a memory allocation
fail or if the amount of requested memory exceeds _HEAP_MAXREQ.
For information about this and other error codes, see
Errno, _doserrno, _sys_errlist and _sys_nerr. The startup code
uses malloc to allocate storage for _environ, envp variables
and argv .
Of the manual POSIX.1-2017 about malloc()
has that note:
The malloc() Function Shall allocate unused space for an Object Whose size in bytes is specified by size and Whose value is unspecified.
The order and contiguity of Storage allocated by successive calls to malloc() is unspecified. The Pointer returned if the allocation
succeeds Shall be suitably Aligned so that it may be Assigned to a
Pointer to any type of Object and then used to access such an Object
in the space allocated (until the space is explicitly Freed or
reallocated). Each such allocation Shall Yield a Pointer to an Object
disjoint from any other Object. The Pointer returned points to the
start (lowest byte address) of the allocated space. If the space
cannot be allocated, a null Pointer Shall be returned. If the size of
the space requested is 0, the behavior is implementation-defined: the
value returned Shall be either a null Pointer or a Unique Pointer
The bold part is what matters in your case. In Portuguese:
The order and continuity of the space allocated by successive calls of
malloc()
is undefined.
This means that you cannot do accounts and draw conclusions about these addresses and differences, as you did in your program.
Back on the show
Over these lines
long int endMemoriaAlocadoPont1 = &*pont1;
long int endMemoriaAlocadoPont2 = &*pont2;
Use shorter names when testing something...
& is the opposite of *. So much so as writing
long int endMemoriaAlocadoPont2 = &*pont2;
endMemoriaAlocadoPont2 = &*&*&*&*&*&*pont2;
endMemoriaAlocadoPont2 = pont2;
dúvida1: The Pont should reserve a memory block for 1 integer which was requested in malloc(), but it reserves 32 bytes or a memory block for 8 integers.
'Cause he does it?
No, the system doesn’t do that. The allocated value is what was passed as argument. It may not even have been allocated, but you haven’t tested after all.
doubt2: If I make a go to the X positions it manages to 'invade' the positions of the block allocated by pont2?
Yes. Within the space allocated to your data. If the amount pointed out is outside your space will cancel the program with the popular exception "Access Violation"
Example
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* pont1 = malloc(sizeof(int));
*pont1 = 4;
printf("Endereco de pont1 = %p\n", &pont1);
printf("pont1 aponta para = %p\n", pont1);
printf("e o valor la = %d\n", *pont1);
int* pont2 = malloc(sizeof(int));
*pont2 = 64;
printf("\nEndereco de pont2 = %p\n", &pont2);
printf("pont2 aponta para = %p\n", pont2);
printf("e o valor la = %d\n", *pont2);
int* outro = malloc(sizeof(int));
memcpy( outro, pont1, sizeof(pont1));
printf("valor de '*outro' com o endereco copiado de pont1 = %d\n\n", *outro);
outro = 1024;
//printf("valor de '*outro' com o endereco 1024 = %d\n\n", *outro);
long int endMemoriaAlocadoPont1 = &*pont1;
printf("Endereco 2: %p\n", endMemoriaAlocadoPont1);
endMemoriaAlocadoPont1 = &*pont1;
printf("Endereco 2: %p\n", endMemoriaAlocadoPont1);
endMemoriaAlocadoPont1 = &*&*&*&*&*&*&*&*&*pont1;
printf("Endereco 2: %p\n", endMemoriaAlocadoPont1);
return 0;
}
It’s practically your show and show
Endereco de pont1 = 012FF85C
pont1 aponta para = 01626CD0
e o valor la = 4
Endereco de pont2 = 012FF850
pont2 aponta para = 01625870
e o valor la = 64
valor de '*outro' com o endereco copiado de pont1 = 4
Endereco 2: 01626CD0
Endereco 2: 01626CD0
Endereco 2: 01626CD0
Pay particular attention to these lines:
int* outro = malloc(sizeof(int));
memcpy( outro, pont1, sizeof(pont1));
printf("valor de '*outro' com o endereco copiado de pont1 = %d\n\n", *outro);
outro = 1024;
//printf("valor de '*outro' com o endereco 1024 = %d\n\n", *outro);
outro
is a pointer to int
and was allocated via malloc(). It is not healthy in general use but as an example can be used memcpy()
and copy an address there to see what’s in the memory at that address.
And the show shows the value 4
as expected, since it is what has in *pont1
.
But if you take the second comment printf()
and try to see the value of the 1024 address...
And 0x400
in the popular decimal is 1024...
In the second doubt it is as follows: The malloc in the *pont1 allocated 32bytes ie in that allocated block fits 8 integers, from pont1[0] to pont1[7]... However in the last FOR I type values up to position 9 position -> point 1[8] = 1111 and point 1[9] = 2222 and not 'error'. The block of *point 1 only goes up to position 7 q vi is that the values of point 1[8] and point 1[9] 'invades' the block allocated by *point 2 as seen I print the value of point 2[0] and point 2[1] and are 1111 and 2222 respectively.
– p.h_compilado