Question

int *ptr;      
ptr=(int *)malloc(sizeof(int)*2);       
ptr=100;    /*What will happen if I put an asterisk(*) indicating *ptr=100? */            
ptr++;        
printf("ptr=%d",*ptr);         
free(ptr);       

So, I wanted the pointer to increment. I allocated a size of 4(2*2) for the pointer. But I couldn't understand how the pointer increments only by 2. And if I put an asterisk int the 3rd line,that is *ptr=100; It shows something else.

Was it helpful?

Solution

If you have int * ptr, then ptr++ increments the pointer by the size of a single int. If int is two bytes on your platform, that's why it increments by two.

*ptr = 100 would store the value 100 at the int pointed to by ptr, i.e. the first of the two ints that you allocated with your malloc() call.

ptr = 100 will attempt to assign the memory address 100 to ptr, which is almost certainly not what you want, as you would lose your reference to the memory you just malloc()ed, and what is at memory location 100 is probably not meaningful for you or accessible to you.

As it currently stands, if you were to do *ptr = 100 and then ptr++, your printf() call would result in undefined behavior since you'd have incremented the pointer to point to uninitialized memory (i.e. the second of the two ints you allocated with your malloc() call), whose contents you then attempt to output.

(*ptr)++ on the other hand would increment that 100 value to 101, leave the value of ptr unchanged, your printf() call would be fine, and output 101. The second of the two ints you allocate would still remain uninitialized, but that's no problem if you don't attempt to access it.

Also, don't cast the return from malloc(), ptr=(int *)malloc(sizeof(int)*2) should be ptr=malloc(sizeof(int)*2), or even better, ptr = malloc(sizeof(*ptr) * 2);

OTHER TIPS

Try this:

int *ptr;
ptr = malloc(2 * sizeof *ptr);
printf("ptr = %p.\n", (void *) ptr); // Examine pointer before increment.
ptr++;
printf("ptr = %p.\n", (void *) ptr); // Examine pointer after increment.

You will see that the value of ptr is incremented by the number of bytes in an int. The C language automatically does pointer arithmetic in units of the pointed-to element. So a single increment of an int pointer in C becomes, at the machine level, an increment of the number of bytes of an int.


Notes

%p is the proper specifier to use when printing a pointer, not %d. Also, the pointer must be cast to void * or const void *.

ptr = malloc(2 * sizeof *ptr); is a cleaner way to allocate memory and assign a pointer than your original code, because:

  • Using sizeof *ptr causes the code to automatically adapt if you ever change the type of ptr. Instead of having to change the type in two places (where ptr is declared and where malloc is called), one change suffices. This reduces opportunities for errors.
  • malloc does not need to be cast to the destination type. It returns a void *, which C will automatically convert to the destination type of the assignment without complaint. (C++ is different.) It will still work if you cast it, but this can mask another problem: If you accidentally do not declare malloc (as by failing to include <stdlib.h>, and compile in an old version of C, malloc will be implicitly declared to return an int, and the cast will mask the error. Leaving the expression without a cast will cause a warning message to be produced when this happens.

This line changes value of address in pointer to some nonsense (100 will not be any valid address):

ptr=100;

Then you increment the pointer to 100 + sizeof(int) because the pointer has type of int* which automatically increments address by amount of bytes to get to the next integer that ptr points to.

At next line you dereference the invalid pointer so your code should crash, but the command is ok if your pointer had valid address:

printf("ptr=%d",*ptr);

To repair your code just don't change the pointer itself but change the data:

int *ptr;      
ptr=(int *)malloc(sizeof(int)*2);       
*ptr=123;    /*What will happen if I put an asterisk(*) indicating *ptr=100? */            
printf("ptr=%d",*ptr);
ptr++;
*ptr=234;     
printf("ptr+1=%d",*ptr);
// you can set or get your data also this way:
ptr[0] = 333;
ptr[1] = 444;
printf("ptr[0]=%d",ptr[0]);
printf("ptr[1]=%d",ptr[1]);
free(ptr);

First thing you need to understand is a POINTER points to ADDRESS, when your assign 100 to ptr, it means your pointer ptr now points to memory location whose address is 100.

Secondly pointer arithmetic depends on type of pointer, in your case ptr is a pointer pointing to integer. SO when you increment ptr, it means it will jump to the memory location of next integer. So, ptr gets incremented by 2 (memory occupied by one int on your platform)

To be simple

ptr=100;

By this you are trying to store a int as an address to a pointer, which Is nonsense.
In other words you are trying to make the pointer ptr to point the address 100, which is not an address.

But by

*ptr=100;

You are trying to store value 100 to the address pointed by ptr, which is valid.

Also

ptr++;

Means that now ptr is pointing to ptr+4 or (ptr+2 for 16 bit compiler like tc) address.

Also for your particular code, you are just changing and incrementing the address pointed by ptr, but you are not storing any value at the address pointed by ptr.
So your code will print garbage value or it may also crash as 100 is not a valid address.

Also you should have done

ptr=(int*)100;

It would remove

warning: assignment makes pointer from integer without a cast [enabled by default]

But still it is undefined behaviour.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top