Removing first X elements from array - c

I have an array named arr of size 1024. So basically I want to delete the 1st X elements of the array. How would I do that? This is what I am thinking:
Make a pointer pointing to the 1st value of the array (arr[0]). Do pointer arithmetic to take it to the X'th element of the array. Then set the arr[0] to the pointer p, which will effectively remove the first X elements? Will this work?
Or is there an easier way to remove the first X elements of the array?

Since the array is global it will exist in memory until your program terminates. But this won't stop you declaring a pointer which points to one of its internal items, and using this pointer as the start of your array. With your notations: char* p = arr + X; This way p[0] will be equal to arr[X], p[1] to arr[X + 1], and so on.

check out the function memmove, if you can. This is a great way to move a chunk of memory quickly.

If arr is declared as char arr[1024]; then you cannot.
If arr is declared as char * arr = (char *)malloc(1024 * sizeof(char)); then: arr += 3
Or declare it as char do_not_use_this_name[1024]; then use char * arr = do_not_use_this_name + 3;

You can treat arr as a circular buffer. However, you cannot access it like a regular array anymore. You would need an interface.
char arr[1024];
int pos = 0;
int size = 0;
#define arr(i) arr[(pos+(i))%1024]
void append (char v) {
arr(size++) = v;
}
void remove_first_x (int x) {
pos = (pos + x) % 1024;
size -= x;
}

You can move the pointer X units and treat that as the start of the array:
int arr[1024]; // could be other type as well
...
int *p = arr;
...
p += X; // x is the number of units you want to move

Based on your requirement to not use memmove and to cause arr[0] to return the result of arr[x], you could do something like this:
char arr[1024];
int arr_size = sizeof(arr) / sizeof(*arr);
char* source;
char* destination;
char* arr_end = arr + arr_size;
//Initialise the array contents
for (destination = arr, source = arr + x; source < arr_end; ++source, ++destination)
*destination = *source;
Keep in mind that this is just shifting the contents of the array backwards by X. The size of the array is still 1024.
Note that this will not do anything with the remaining X elements at the end of the array. If you want to zero them, you could subsequently do something like this:
for (; destination < arr_end; ++destination)
*destination = 0;

Related

In C/C++: How can i implement a 2D int array using two single pointers (no use of **int)?

I am exploring pointer "mechanics" in C/C++. I try to understand if and how is possible to implement a 2D matrix using two pointers (one for "rows" and one for "columns") instead of a single double pointer. I am aware that a matrix with rows*columns number of values could be stored in memory sequentially, but i am looking to comprehend deeper the mechanics of pointers and eventually to implement a function similar to
int value=getValue(vectorNr,vectorValue)
that is able to "simulate" the construct
value=Matrix[vectorNr][vectorValue]
vectorPointer vectorValue
| AddressV1 |------|valAddr11 valAddr12 valAddr13 |
| AddressV2 |------|valAddr21 valAddr22 valAddr23 |
| AddressV3 |------|valAddr31 valAddr32 valAddr33 |
I tried to begin writing a code like this but I quickly get stuck on pointer arithmetic and address offsetting. I also might chose a very dirty approach so any comment is welcome.
CODE TO IMPLEMENT A 2D ARRAY WITH POINTERS (BUT NOT USING DOUBLE POINTERS). To avoid confusion between rows and columns I refer to "Vectors as rows" and "Columns as vector values"
int vectorsNumber = 3; //Number of Vectors
int valuesNumber = 3; //Number of values stored in one Vector
//Addresses of Vectors. Since Vectors holds a reference to set of values, vectorPointer will hold an address for every set.
void* vectorPointer = malloc(vectorsNumber *sizeof(void*));
//Populating the vectorPointer with the address generated by allocating memory for every set of values
for (int i = 0; i < vectorsNumber; i++)
{
vectorPointer = (int*)malloc(valuesNumber * sizeof(int)); //Values shall be of int types
vectorPointer++; //ILLEGAL since cannot perform arithmetic on pointers of type void. What do do??
}
//Restore the initial address. In any case...ILLEGAL arithmetic. What do do??
for (int i = 0; i < vectorsNumber; i++)
{
vectorPointer--; //Restore the initial address. In any case...ILLEGAL arithmetic.
}
//Declaring the pointer to hold the address of one value. Memory was already allocated before
int* valueAddress;
for (int j = 0; j < vectorsNumber; j++)
{
//Getting the address of the first value of the first Vector
valueAddress = (int*)vectorPointer; //Is this casting valid in C language?
//Populating the value with whatever operation
for (int k = 0; k < valuesNumber; k++)
{
*valueAddress = (k + 1)*(j + 1); //populate the Vector with int values
}
vectorPointer++; //Switch to next Vector.ILLEGAL arithmetic
}
Actually, you only need one pointer. One way of doing it is by allocating enough memory to hold all the values, and then have functions that map the x/y values in the array to the respective memory location. Assume we want those to be the dimensions and our array variable:
int dimX = 10, dimY = 5;
int *array;
You can set a value this way:
void arraySet(int value, int x, int y) {
array[x + dimX * y] = value;
}
And get a value this way:
int arrayGet(int x, int y) {
return array[x + dimX * y];
}
Allocate the memory beforehand such as in the main function:
array = malloc(sizeof(int)*dimX*dimY);
Use it like this:
arraySet(123, 9, 3); // sets the value of [9, 3] to 123
printf("Memory at 9, 3 is %d\n", arrayGet(9, 3));
This "two pointers" idea doesn't make any sense and the code you posted cannot be salvaged. What you should do instead is to use a pointer to a 2D array:
int (*ptr)[x][y] = malloc(sizeof *ptr);
...
free(ptr);
That's it. However, a pointer to a 2D array is cumbersome, since we have to de-reference it before accessing the actual array. That is, we'd end up writing (*ptr)[i][j] = ...; which is ugly.
To dodge this, we can instead still allocate a 2D array, but instead of pointing at "the whole array", we point at the first element, which is a 1D array:
int (*ptr)[y] = malloc( sizeof(int[x][y]) );
...
ptr[i][j] = ... ; // more convenient syntax for access
...
free(ptr);
More info: Correctly allocating multi-dimensional arrays
You can simulate int a[2][3]; with
one dimensional array and index computing:
int* matrix = (int*) malloc(6 * sizeof(int));
int get_matrix_2_3(int* matrix, int i, int j) { return matrix[3 * i + j]; }
2-dimensional array:
int** matrix = (int**) malloc(2 * sizeof(int*));
for (int i = 0; i != 2; ++i) {
matrix[i] = (int*) malloc(3 * sizeof(int));
}
matrix[1][2] = 42;

Accessing an int array passed as void pointer segfaults

I'm playing with pointers and stumbled accross this problem. Like in this question I wanted a generic method signature for function foo, therefore I chose void * input as parameter. For testing reasons I casted the void pointer to an int ** pointer to use it like an 2D array.
#include <stdio.h>
#include <stdlib.h>
void * foo(void *input, size_t mySize)
{
for (size_t i = 0; i < mySize; ++i)
{
for (size_t j = 0; j < mySize; ++j)
{
((int **)input)[i*mySize][j] = 10*i+j;
}
}
return input;
}
int main(int argc, char const *argv[])
{
size_t const mySize = 10;
void * myMemory, * testPtr;
myMemory = malloc(mySize * mySize * sizeof(int));
testPtr = foo(myMemory, mySize);
free(testPtr);
return 0;
}
Now I thought that using the [] operator would be same as adding an int to the pointer, e.g. that ((int **)input[i][j] would be the same like `((int **)input)+i+j
But accessing the input array in foo segfaults and using gdb shows me
(gdb) p ((int **)input)[i][j]
Cannot access memory at address 0x0
(gdb) p ((int **)input)+i+j
$25 = (int **) 0x405260
so obviously there is a difference. And therefore I'm confused.
While arrays and pointers are similar, they are not the same.
An array - single or multi dimensional - depicts a continuous chunk of memory, containing a specific datatype. For exampleint arr [10] declares arr as 10 continuous ints in memory. int multi_arr[5][10] declares multi_arr as 5 arrays of 10 continuous ints in memory.
Furthermore, the name arr would be the base address of this array, and passing it to a function would be the same as passing &arr[0].
But this is where the similarities end. A multi dimensional array can't (technically) be cast to a pointer-to-a-pointer and then back again.
If arr above pointed to a block of ints, then dereferencing the first dimension of int ** ptr would lead you to a block of pointers toint. Dereferencing that would not take you deeper into that block, as a multi dimensional array would, rather it could point anywhere.
You allocated a one dimension array with mySize*mySize elements.
int** is an array of pointers to int, what you want is
int **array2d;
int *p;
array2D = malloc(ROWS * sizeof(int*) + ROWS * COLUMNS * sizeof(int));
p = (int*) &array2d[ROWS];
for (size_t i = 0; i < ROWS; ++i)
array2d[i] = &p[i * COLUMNS];
now array2d[row][column] can work.
Or, as already suggested, use a one dimension array and use the array[row * COLUMNS + column] formulae.

Generic bidimensional array

I want to create a bidimensional array like so:
void **mdeclaraMatrice(int nrLini,int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * 4);
if(m==NULL)
return NULL;
for(i=0; i<nrLini; i++)
{
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
if(*(m + (i*4)) == NULL)
return NULL;
}
return m;
}
I whant to use it like this:
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
but it doesn't work. What do I do wrong?
You should use m[i] instead of *(m+i*4) and let the compiler do the arithmetic.
In addition, you should deallocate the already-allocated memory in case of a failure.
Try this instead:
void **mdeclaraMatrice(int nrLini, int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * sizeof(void*));
if (m == NULL)
return NULL;
for (i=0; i<nrLini; i++)
{
m[i] = malloc(nrColoane * sizeOfElement);
if (m[i] == NULL)
{
while (i-- > 0)
free(m[i]);
free(m);
return NULL;
}
}
return m;
}
[not an answer to the question, but to the indented usage of the proper answer as given by others]
To access the void pointer array as an array of int, doing this
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
is not correct, as per the C-Standard only void* converts to any other pointer properly, void** doesn't necessarily. So it shall correctly be
void ** ppv = mdeclaraMatrice(n,m,sizeof(int));
int * pi = *ppv; /* Please note, there is NO casting necessary here! */
Then access the members like so:
pi[0] = 42
pi[1] = 43;
...
Which essently is the same as doing
*((int *) (pi + 0)) = 42;
*((int *) (pi + 1)) = 43;
which indeed does not make sense really as pi already is int*, so the fully correct approach (also taking into account the 2nd dimension) would be:
((int *)(ppv[0]))[0] = 42;
((int *)(ppv[0]))[1] = 43;
Which could be made usable by definging a macro:
#define GENERIC_ARRAY_ELEMENT(type, address, r, c) \
((type *)(address[r]))[c]
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 0) = 42;
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 1) = 43;
I will address the problem of allocation an array of void pointers and then interpreting them as an array of int pointers.
int **nope = (int **)mdeclaraMatrice(n,m,sizeof(int));
Even assuming the allocation was completely correct the assignment and later usage of nope is undefined behavior. void** and int** have incompatible types.
What you can do is the following. Assign the void pointers one by one to an array of int pointers.
void** arrp = mdeclaraMatrice(n,m,sizeof(int));
int* arr[n] ;
for( size_t i = 0 , i < n ; i++ )
arr[i] = arrp[i] ;
And then use the arr array, When you want to free the memory you free the original pointer:
free( arrp ) ;
The problem occurs in this line:
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
You have to know that when adding a number to an address, the address will be incremented by the number times the size of the object the address points to. So if your pointer points to an object that is of size 4 bytes, and you add 1 to it, then the address will automatically be incremented by 4, not by 1. So you should abandon *4.
Also, use the sizeof operator when allocating space, because addresses (and thus pointers) can have different sizes on different processor architectures.
Actually, you don't even need your generic 2D array function if you know the powerfull VLA features of C99. To allocate a true 2D array (no index array required), you just do this:
int (*twoDIntArray)[width] = malloc(height*sizeof(*twoDIntArray));
That's it. Accesses are just as simple:
twoDIntArray[line][column] = 42;
In this code, twoDIntArray is a pointer to an array of width integers. The malloc() call simply allocates enough space for height such line arrays. When you do the pointer arithmetic twoDIntArray[line], you add the size of line line arrays to the pointer, which produces the address of the corresponding line array. This line array is then indexed by the second array subscript [column].
Needless to say that freeing such an array is just as trivial:
free(twoDIntArray);

Pointer to an array and Array of pointers

As I am just a learner, I am confused about the above question. How is a pointer to an array different from array of pointers? Please explain it to me, as I will have to explain it to my teacher. Thank you.
Pointer to an array
int a[10];
int (*ptr)[10];
Here ptr is an pointer to an array of 10 integers.
ptr = &a;
Now ptr is pointing to array of 10 integers.
You need to parenthesis ptr in order to access elements of array as (*ptr)[i] cosider following example:
Sample code
#include<stdio.h>
int main(){
int b[2] = {1, 2};
int i;
int (*c)[2] = &b;
for(i = 0; i < 2; i++){
printf(" b[%d] = (*c)[%d] = %d\n", i, i, (*c)[i]);
}
return 1;
}
Output:
b[0] = (*c)[0] = 1
b[1] = (*c)[1] = 2
Array of pointers
int *ptr[10];
Here ptr[0],ptr[1]....ptr[9] are pointers and can be used to store address of a variable.
Example:
main()
{
int a=10,b=20,c=30,d=40;
int *ptr[4];
ptr[0] = &a;
ptr[1] = &b;
ptr[2] = &c;
ptr[3] = &d;
printf("a = %d, b = %d, c = %d, d = %d\n",*ptr[0],*ptr[1],*ptr[2],*ptr[3]);
}
Output:
a = 10, b = 20, c = 30, d = 40
Background
Think of pointers as just a separate data type. They have their own storage requirements -- such as their size -- they occupy 8 bytes on a x86_64 platform. This is the case of void pointers void*.
In those 8 bytes the information stored is the memory address of another piece of data.
The thing about pointers is that since they "point" to another piece of data, it's useful to know what type that data is too so you can correctly handle it (know its size, and structure).
In stead of having their own data type name such as pointer they compose their name based on the data type they refer to such as int* a pointer to an integer. If you want a plain pointer without type information attached to it you have the option of using void*.
So basically each pointer (to int, to char, to double) is just a void* (same size, same use) but the compiler knows the data being pointed to is of type int and allows you to handle it accordingly.
/**
* Create a new pointer to an unknown type.
*/
void* data;
/**
* Allocate some memory for it using malloc
* and tell your pointer to point to this new
* memory address (because malloc returns void*).
* I've allocated 8 bytes (char is one byte).
*/
data = malloc(sizeof(char)*8);
/**
* Use the pointer as a double by casting it
* and passing it to functions.
*/
double* p = (double* )data;
p = 20.5;
pow((double* )data, 2);
Pointer to array
If you have an array of values (let's say integers) somewhere in memory, a pointer to it is one variable containing its address.
You can access this array of values by first dereferencing the pointer and then operating some work on the array and its values.
/**
* Create an array containing integers.
*/
int array[30];
array[0] = 0;
array[1] = 1;
...
array[29] = 29;
/**
* Create a pointer to an array.
*/
int (*pointer)[30];
/**
* Tell the pointer where the data is.
*/
pointer = &array;
/**
* Access the data through the pointer.
*/
(*pointer)[1] = 999;
/**
* Print the data through the array.
* ...and notice the output.
*/
printf("%d", array[1]);
Array of pointers
If you have an array of pointers to values, the entire array of pointers is one variable and each pointer in the array refers to somewhere else in the memory where a value is located.
You can access this array and the pointers inside it without dereferencing it but in order to reach a certain value from it you will have to dereference one of the pointers inside the array.
/**
* Create an array containing pointers to integers.
*/
int *array_of_pointers[30];
array_of_pointers[0] = 0;
array_of_pointers[1] = 1;
...
array_of_pointers[29] = 29;
POINTER TO AN ARRAY
Pointer to an array will point to the starting address of the array.
int *p; // p is a pointer to int
int ArrayOfIntegers[5]; // ArrayOfIntegers is an array of 5 integers,
// that means it can store 5 integers.
p = ArrayOfIntegers; // p points to the first element of ArrayOfIntegers
ARRAY OF POINTERS
Array of pointers will contain multiple pointers pointing to different variables.
int* ArrayOfPointers[2]; // An array of pointers which can store 2 pointers to int
int A = 1;
int B = 2;
int *PointerToA ;
PointerToA = &A ; // PointerToA is a pointer to A
int *PointerToB ;
PointerToB = &B ; // // PointerToA is a pointer to A
ArrayOfPointers[0] = PointerToA ; // ArrayOfPointers first element points to A
ArrayOfPointers[1] = PointerToB ; // ArrayOfPointers second element points to B
An array of pointers is this - int* arr[3]; will contain multiple pointers pointing to 3 different variables
Pointer to an array is this - int (*arr)[3]; will point to first element of an array of 3 elements
Below is a sample code which might help you more
int array[3];
array[0] = 1;
array[1] = 2;
array[2] = 3;
int* point = array; // pointer of an array
int* points[3];
points[0] = &array[0];
points[1] = &array[1];
points[2] = &array[2]; // an array of pointer
I'm not sure if i get the question right but I will try to point this out.
There are pointers pointing to a type
e.g.:
int num;
int* p_num = &num; // this is pointing at the int
Moreover there are arrays (which in fact are pointers)
int num; // an Integer
int* p_num; // a pointer. (can point at int's)
int arr[3]; // an Array holding 3 int's
arr[0] = 1; // + holding the values 1, 2, 3
arr[1] = 2;
arr[2] = 3;
p_num = arr; // because an array is just a pointer "p_num" num is now pointing at
// + the first element in the array.
// + ** THIS IS NOW A POINTER TO AN ARRAY **
num = *p_num;// num = 1
And there are arrays, which can hold multiple pointers:
int num1;
int num2;
int num3;
int* p_array[3]; // an array holding 3 pointer to int's
p_array[0] = &num1; // this is pointing at num1
p_array[1] = &num2; // num2, ...
p_array[2] = &num3;
// ** THAT IS AN ARRAY OF POINTERS **
I often resort to pen and paper when thinking about c pointers.
Pointer to an array
[a] -> [b]
[c]
[d]
.
.
.
An array of pointers
[a] -> [j]
[b] -> [k]
[c] -> [l]
. .
. .
. .
A pointer to an array contains the memory location of an array. Whereas an array of pointers contains lots of memory locations, which contain single values (or possibly other arrays, or arrays of pointers ;).
Pointer to an array
#include <stdio.h>
#include <stdlib.h>
void main(void) {
int i;
int *ptr, *loopPtr;
ptr = malloc(10 * sizeof(int)); // allocate an array of 10 ints on the heap
loopPtr = ptr; // copy pointer into temp pointer
for(i=0; i < 10; i++) {
*loopPtr = i; // dereference pointer and store i in it
loopPtr++; // move pointer to next memory location
}
loopPtr = ptr; // copy pointer into temp pointer
for(i=0; i < 10; i++)
printf("%d, ",*(loopPtr++)); // move across array printing
printf("\n");
free(ptr); // free memory allocated on the heap
}
An array of pointers
#include <stdio.h>
#include <stdlib.h>
void main(void) {
int i;
int *ptr[10]; // an array of pointers
// allocate 10 ints on the heap pointed to by an array
for(i=0; i < 10; i++)
ptr[i] = malloc(sizeof(int));
for(i=0; i < 10; i++)
*ptr[i] = i; // dereference pointer and store i in it
for(i=0; i < 10; i++) // iterate through array and dereference pointers
printf("%d, ",*ptr[i]);
printf("\n");
for(i=0; i < 10; i++)
free(ptr[i]);
}
The best way to contrast the difference is probably with the malloc() calls, one returns a pointer to an array of 10 ints and the other returns 10 pointers to individual ints.

What does this C function do?

double *f(int n, double v)
{
double *a, *p;
a = malloc(n * sizeof(double));
if (a != NULL)
for (p = a; p < a + n; p++)
*p = v;
return a;
}
Can you explain me what this function is needed for? Does it copy the content of v in n? If yes, why does it return a? I really don't get it... Thanks in advance.
It returns a newly allocated double array of size n filled with value v, or NULL if the allocation fails.
This loop:
for (p = a; p < a + n; p++)
*p = v;
uses pointer arithmetic. As p is a pointer to a double, incrementing it will point to the next double to write. *p = v writes the double at the specified location.
double *f(int n, double v)
{
double *a, *p;
a = malloc(n * sizeof(double)); // allocate memory enough for "n" doubles (an array)
if (a != NULL) // if the allocation was successful
for (p = a; p < a + n; p++) // loop from the beginning of the array to the end
*p = v; // fill every element of the array with the value "v"
return a; // return the new array
}
So if I called this function:
double * myarray;
myarray = f(3, 1.3);
Now I have:
myarray[0] = 1.3
myarray[1] = 1.3
myarray[2] = 1.3
So to answers your questions:
Can you explain me what this function is needed for?
allocates and initializes an array of doubles.
Does it copy the content of v in n?
No. Considering v is a double and n is an int, that doesn't even make sense. It makes an array n large and initializes it with the value v.
If yes, why does it return a?
It returns a so you have a reference to the newly created array. (see example above on how it could be used)
It allocates an array of n doubles, initialising each element of the array to the value of v.
The function returns a to allow the caller to use this newly allocated array.
It allocs a memory area of n * sizeof(double) bytes and enterely fill it with v value
Allocate an array of n doubles in heap, fill it with v and return the pointer to it?
Duplicate the v n times into an array of float
The array is allocated in the function and contains n float elements.
at the end of the function each element in the array a is containing v as value

Resources