Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move to a pointer position directly without using the ++ operator?

I'm working with a pointer to a structure. I want to know if is possible move directly to a specific position without use ++ operator.

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

#define ARRAY_SIZE 10

struct dummy{
    int id;
    char buffer[10];
};

typedef struct dummy dummy_struct;

int main()
{
    int i=0;
    dummy_struct *ds = malloc(sizeof(dummy_struct)*ARRAY_SIZE);
    dummy_struct *iterator = ds;

    for(i=0;i<ARRAY_SIZE;i++)
    {
        iterator->id = i;
        sprintf(iterator->buffer,"%d",i);
        iterator++;
    }

    iterator = ds;

    for(i=0;i<ARRAY_SIZE;i++)
    {
        printf("%d:%s:%p\n",iterator->id,iterator->buffer,iterator);
        iterator++;
    }

    // I want to access directly to 5th position
    iterator = ds + (sizeof(dummy_struct)*5);
    printf("5th position %d:%s:%p\n",iterator->id,iterator->buffer,iterator);

    return 0;
}

This statement

iterator = ds + (sizeof(dummy_struct)*5);

is not working. I will appreciate any suggestion.

like image 859
Rubén Pozo Avatar asked Dec 13 '17 08:12

Rubén Pozo


1 Answers

Well, pointer arithmetic honors the data type!!

iterator = ds + 5;

will get the job done.

To elaborate, the above expression will produce a pointer by moving it 5 times, multiplied by the size of type for ds, in bytes. That's the same as &(ds[5]).

For sake of completeness, explaining why iterator = ds + (sizeof(dummy_struct)*5); is wrong, is, here, you're essentially trying to move the pointer to an element with index as (sizeof(dummy_struct)*5 which is, well out of bounds. Note please, this invokes undefined behavior!! note below

Quoting C11, chapter §6.5.6/P8

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. [....]

and then, regarding the undefined behavior mentioned above,

[....] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.


That being said, the printf() statement is also erroneous. You have two conversion specifiers, but supplied three arguments. It's not harmful, but useless/meaningless.

Related, from chapter §7.21.6.1/P2,

[...] If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored. [...]

Based on this case, you can directly use

printf("5th position %d:%s:\n",ds[5].id,ds[5].buffer);
like image 63
Sourav Ghosh Avatar answered Sep 19 '22 04:09

Sourav Ghosh