w33haa
w33haa

Reputation: 314

Dereference operator (*) differences between char* and int*

Why is the operator (*) needed to access the value of an int* variable but not for char*?

char *char_ptr; 
int *int_ptr;
int mem_size = 50;

char_ptr = (char *) malloc(mem_size);
strcpy(char_ptr, "This is memory is located on the heap.");
printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);


int_ptr = (int *) malloc(12);
*int_ptr = 31337; 
printf("int_ptr (%p) --> %d\n", int_ptr, *int_ptr);

Output:

char_ptr (0x8742008) --> 'This is memory is located on the heap.' 
int_ptr (0x8742040) --> 31337

Upvotes: 5

Views: 151

Answers (4)

Adrian Mole
Adrian Mole

Reputation: 51825

This is because of the way the printf format specifiers work: the %s format expects, for its corresponding argument, a pointer to a character (more precisely, the address of a nul-terminated string - which can be an array of char, an allocated buffer with at least one zero byte in it, or a string literal), so you can just give it the char_ptr variable as-is; on the other hand, the %d format expects an integer (not a pointer-to-integer), so you have to dereference the int_ptr variable using the * operator.

Note on Good Programming Style: As mentioned in the comments to your question, be sure to call free() at some point on every buffer allocated with malloc, or you will introduce memory leaks into your code. Also see: Do I cast the result of malloc?.

Upvotes: 7

"Why is operator (*) needed to access the value of an int* variable and not for char* ?"

Because at the printf() function, the format specifier %s expects a matching argument of type char * - a pointer to a string, while %d expects an argument of type int.

In the latter case, the dereference operator * is required to dereference int_ptr and yield the value of the int object int_ptr points to.

As char_ptr is already of type char* as required by %s, there is no need to dereference it.


Side notes:

1.

int_ptr = (int *) malloc(12);

Note that with 12 Bytes on most modern system you be able to allocate only 1 int object as it requires 8 Byte. The remaining 4 Byte are not sufficient to hold another.

If you want to allocate space for only one int, use sizeof(*int_ptr):

int_ptr = (*int) malloc(sizeof(*int_ptr));

2.

Also don´t forget to free() the storage allocated by malloc() after its use:

free(int_ptr);
free(char_ptr);

3.

Furthermore there is no need to cast the return value of malloc(): Do I cast the result of malloc?

char_ptr = malloc(mem_size);
int_ptr = malloc(sizeof(*int_ptr));

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409176

For any pointer or array p and index i, the expression p[i] is exactly equal to *(p + i). From that follows that *p is equal to p[0].

In your case *int_ptr is equal to int_ptr[0].

If you did the same with char_ptr (i.e. *char_ptr) you would have char_ptr[0] which is a single character, that could be printed with %d as well:

printf("char_ptr (%p) --> '%d'\n", char_ptr, *char_ptr);

This would print the decimal representation of the first character in the string.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

You also can use the expression *char_ptr. It has the type char and the expression will yield the pointed character that is 'T' - the first character of the stored string literal.

This is the same as *int_ptr that returns the first element of the allocated integer array.

As for the conversion specifier %s then it expects an argument of the type char * that points to a string. On the other hand, the conversion specifier %d expects an object of the type int

You could use the conversion specifier %c. to output just a single character of the pointed string like

printf( "%c", *char_ptr );

Upvotes: 0

Related Questions