Reputation: 2399
int* pInt = malloc(512);
char* pChar = malloc(512);
I have a hard time to grasp the concept. Pointer type has the same size, 4 or 8 bytes, depending on the system. int has 4 bytes, and char has 1 byte. Here, I am allocating 512 bytes to each pointer of type int and char. Those pointers should have the same size (block of memory). I understand that they point to different blocks of memory which both have 512 bytes. BUT how are they different?
Upvotes: 3
Views: 1305
Reputation: 16650
Both statements are assignment expressions. An assignment has two sides: the left one, that denotes to whom a value is assigned and the right one, that denotes the value to assign.
In your example the right side reserves the memory: malloc(512)
. Doing so, nothing is said about the usage of that block, esp. nothing is said about what type of data there is stored. In both cases malloc(512)
do exactly the same. There is no difference. Memory blocks reserved by malloc()
never has a type out of themselves.
malloc()
returns a pointer to the memory block. Since it has no idea about the data stored there this is a void-pointer, an "untyped" pointer. Assigning this to a typed pointer, will have effects:
First of all you bring semantics into it. Nobody can say, what kind of data is stored in the block whose address is returned by malloc()
. When you assign it to an int pointer, it says: "There are ints stored in that block." Analogue with char pointers.
Second, you tell the compiler something about the data stored there, when you do operation with it: I. e. if you store a value into the memory block using a char pointer as pChar
, only one byte of the block will be affected. This is, because chars have the size of one byte by definition.
If you store a value into the memory block using an int pointer as pInt
, 4 or 8 (or whatever on your machine) are affected.
But this depends on the way you refer the memory block, the type of the pointer. The memory block itself is still typeless. Therefore you can change the type:
int* pInt = malloc(512); // A typeless memory block referred by an int pointer
*pInt = 4; // Will affect 4 (or 8 or whatever) bytes
char* pChar = (char*)pInt; // A char pointer referring *the same* typeless memory block
*pChar = 'M'; // Will affect one byte
So, the memory block does not have any type. The pointer to memory inside the memory block gives a type to the access to the block. The block itself is stilled typeless.
Upvotes: 1
Reputation: 10064
int *pInt = malloc(512)
is similar to int pInt[128];
char *pChar = malloc(512)
is similar to char pChar[512];
Note ints are 4 bytes large and 512 / 4 = 128. (Sometimes ints are not 4 bytes large. It depends on the compiler.)
The blocks themselves are not different. Rather, their differing types affect how the compiler treats those blocks of memory. The compiler does not allow you to freely switch between types, but you can do so anyways through typecasting, ie (char *)pInt;
for example.
Below is some code that manipulates pInt
and pChar
to demonstrate their relationship. Note the use of typecasting to avoid compiler errors.
#include <stdio.h>
#include <stdlib.h>
static const int BLOCKSIZE = 8;
void print_as_chars(char *print_me)
{
int i;
for (i = 0; i < BLOCKSIZE; ++i)
{
printf ("%4d ", print_me[i]);
}
printf ("\n");
}
void print_as_ints(int *print_me)
{
int i;
for (i = 0; i < BLOCKSIZE / sizeof(int); ++i)
{
printf ("%19d ", print_me[i]);
}
printf("\n");
}
int main (void)
{
int *pInt = malloc(BLOCKSIZE);
char *pChar = malloc(BLOCKSIZE);
// We can set any value in pInt
pInt[0] = 25;
pInt[1] = 300;
// But represent the memory in any way we want.
printf ("pInt:\n");
print_as_ints(pInt); // 25 300
print_as_chars((char *)pInt); // 0 0 0 25 0 0 1 44
printf ("\n");
// It works both ways!
pChar[0] = 0; pChar[1] = 0; pChar[2] = 0; pChar[3] = 25;
pChar[4] = 0; pChar[5] = 0; pChar[6] = 1; pChar[7] = 44;
printf ("pChar:\n");
print_as_ints((int *)pChar); // 25 300
print_as_chars(pChar); // 0 0 0 25 0 0 1 44
printf ("\n");
return 0;
}
Upvotes: 0
Reputation: 47932
You're right. pInt
and pChar
are pretty similar. (If you look at the emitted machine code, they're probably identical -- so far.)
The difference comes when you use the pointers. When you say
*pChar = 0;
you'll set 1 byte pointed to by pChar
to 0. But when you say
*pInt = 0;
you'll set a whole int's worth of memory to 0.
Upvotes: 3
Reputation: 182763
They both point to 512-byte blocks of memory. There are really only two differences:
1) When you dereference them, pInt
will store and load integer values while pChar
will store and load character values.
2) pInt[1]
will refer to the second integer sized chunk of the block of memory pInt
points to. pChar[1]
will refer to the second character-sized chunk of the block of memory pChar
points to.
So:
*pInt = 0;
Sets to the integer value zero the first integer-sized chunk of memory in the block pInt
points to.
*pChar = 0;
Sets to the character value zero the first character-sized chunk of memory in the block pChar
points to.
Upvotes: 5