change array pointer in C

114 Views Asked by At

I have a fixed size array and i want to 'left shift' it.

e.g {1,2,3,4} --> {2,3,4}

from my understanding arrays are consecutive memory cells, so this should be possible by just changing the start pointer.

is this possible in C?

I tried

array = &array[1];

but I get error: assignment to expression with array type

I can do

char* array1;
array1 = &array2[1];

and use array1, but this introduces another variable and id like, if possible, to use less memory

2

There are 2 best solutions below

10
Vlad from Moscow On

Arrays are non-modifiable lvalues. So this statement

array = &array[1];

is incorrect.

This introducing a pointer

char* array1;
array1 = &array2[1];

does not shift to the left elements of the array. They stay in their original positions. There is only declared a pointer that points to the second element of the array.

To shift to the left elements in an array you need to copy following elements to preceding elements. If to shift only to one position you can use standard C string function memmove or to use a loop. For example

#include <string.h>

//...

int array[] = { 1, 2, 3, 4 };
const size_t N = sizeof( array ) / sizeof( *array );

memmove( array, array + 1, ( N - 1 ) * sizeof( *array ) );

Pay attention to that the actual size of the array will not be changed. Arrays are extents of memory of fixed sizes.

0
chqrlie On

If the array is defined as an object with local or global scope like

int array[] = { 1, 2, 3 };

The is no way to reduce the memory it uses when you no longer need the full array. You can use pointers to access portions of the array as int *p = &array[1]; (or equivalently int *p = array + 1;) but it does not reduce the memory used, furthermore you cannot use the same identifier array for this because array refers to the array object itself, it is not a pointer you can change.

Conversely, if the array was allocated from the heap with malloc() or calloc(), you can try and reduce the memory it uses by copying the portion you want to keep over the beginning of the array and calling realloc() to try and discard the portion you no longer use:

    size_t initial_size = 1000;
    int *array = calloc(sizeof *array, initial_size);

    // ... do some work

    // now we only need the 100 elements at index 200 to 299
    // try and reduce the memory used

    memmove(array, &array[200], sizeof(*array) * 100);
    int *newp = realloc(array, sizeof(*array) * 100);
    if (newp != NULL) {
        // reallocating was successful, and newp might be different from array.
        // note that there is no guarantee any memory was actually released
        // back to the system.
        array = newp;
    } else {
        // realloc failed. While this is unlikely for a size reduction, you
        // must test for potential failure and do nothing, array still points
        // to the original block of memory
    }