-2

Below code i'm trying to perform pointer Arithmetic

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = malloc(100);

    printf("base : %p\n", ptr);
    printf("\n");
    printf("base+1 : %p\n", ptr+1);

    ptr+= 100;
    *ptr = 90;
    printf("addr: %p val : %d\n", ptr, *ptr);

    return 0;
}

output:

base : 0x5621e46412a0

base+1 : 0x5621e46412a4
addr: 0x5621e4641430 val : 90

question:

  1. malloc (100); will it return 100 bytes ?
  2. Here i'm not typecasting return addr of malloc, BTW malloc will return void type correct how ptr+1 increments 4 byte ?
  3. Now incrementing ptr+100, so 400 byte will get incremented correct ? also i can able to assign value with out segmentation fault how it works ?

Trying to understand how pointer arithmetic works in this case

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • Looks like your ptr++ moved the pointer by 4 bytes. Looks like you're in a 32 bit environment. – Pete Apr 14 '23 at 18:05
  • If you want 100 _elements_ in `ptr`, you need: `int *ptr = malloc(sizeof(*ptr) * 100);` In _your_ code, you _only_ allocate space for `100 / sizeof(int)` elements --> 25 elements. The `malloc` arg is number of _bytes_ and not number of _elements_. It doesn't know what type of pointer gets its return value. Also, even with the corrected `malloc`, doing `ptr += 100; *ptr = 90;` is UB (undefined behavior) because you are one element past the end of the allocated area. UB means: may work [seemingly], may produce "funny" results, may segfault, etc. – Craig Estey Apr 14 '23 at 18:06
  • https://en.cppreference.com/w/c/memory/malloc – Pete Apr 14 '23 at 18:06

3 Answers3

2

malloc (100); will it return 100 bytes ?

Yes. Or more precise: It will reserve 100 bytes for you and return the address of that memory area. See malloc

Here i'm not typecasting return addr of malloc, BTW malloc will return void type correct how ptr+1 increments 4 byte ?

That is not correct. malloc does not return void but pointer to void. This is compatible with any pointer to any data without a cast. After assigning to ptr it is a pointer to int. The increment only depends on the type of the pointer, i.e. int.

Now incrementing ptr+100, so 400 byte will get incremented correct ? also i can able to assign value with out segmentation fault how it works ?

Correct (given that you seem to work with a 32bit system). That means you are illegally accessing memory you do not own and you are not supposed to access. This results in undefined behaviour. It can seem to work or crash. Undefined behaviour also means it is not defined to cause a segfault.

See Undefined, unspecified and implementation-defined behavior

Gerhardh
  • 11,688
  • 4
  • 17
  • 39
  • Re “This is compatible with”: Compatible has a technical meaning in the C standard. It essentially means two types can be completed to be the same type. E.g., `int a[]` and `int a[3]` are compatible because missing length in the former can be completed to be the same length as in the latter. `void` cannot be completed (by rule), so `void` is not compatible with any different type. `void *` and `int *` cannot be completed to be the same, so they are not compatible. Assignment implicitly converts, and `void *` can be converted to any pointer-to-object type. – Eric Postpischil Apr 14 '23 at 18:16
0
  1. No; it will return a pointer to at least 100 bytes, or NULL.
  2. No; it increments by sizeof(*ptr) which in this case is sizeof(int). That could be a different value than 4. A ptr-to-void is assignment-compatible to any object pointer without a cast and in C it is best practice to not cast the malloc return value. Search this site for the reasons.
  3. Not correct; it increments by 100*sizeof(*ptr). That could be a value other than 400. Writing through that pointer is undefined behavior, so anything could happen, including nothing noticeable.

To print pointer values, it is not sufficient to use the %p format specifier, the argument must be a pointer-to-void, so you must use (void*) casts as in

printf("base : %p\n", (void*)ptr);
Jens
  • 69,818
  • 15
  • 125
  • 179
0
  1. malloc (100); will it return 100 bytes ?

malloc(100) will return either a pointer to where 100 bytes of memory has been reserved or a null pointer.

  1. Here i'm not typecasting return addr of malloc,…

The simple assignment operator (=) automatically converts its right operand to the type of the left operand. When the left operand is a pointer, the right operand may be either of:

  • a pointer to a compatible type or to void except that the right type may omit qualifiers that the left type has or
  • a null pointer constant.

BTW malloc will return void type correct how ptr+1 increments 4 byte ?

C does not “remember” that an address came from malloc with return type void *. When ptr+1 is evaluated, the type of ptr is used for the arithmetic. The type of ptr is int *, so the arithmetic is performed in units of int.

  1. Now incrementing ptr+100, so 400 byte will get incremented correct ?

Within the allocated space, adding x will add 4x bytes to the address, if the C implementation uses four bytes for int. Outside of the allocated space, the C standard does not define the behavior of pointer arithmetic. If the allocated space were 1000 bytes instead of 100, then ptr+100 would calculate the address 400 bytes beyond the start.

… also i can able to assign value with out segmentation fault how it works ?

Memory protect usually works in units of pages. If you use memory that is within a page you have access to, there is no segmentation fault even if it is not a place in the page you should be accessing the way you access it. Or, if you calculate an address incorrectly and the result is still a page you have access to, there is no segmentation fault. Memory protection does not absolutely prevent all address mistakes by a process, and dynamically allocated memory is likely to be in a region with many pages that the program is permitted to access.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312