C++: Modifying Array Via Function

Changing array inside function in C

In c you can't pass a variable by reference, the array variable that you assign inside the function contains initially the same address as the passed pointer, but it's a copy of it so modifying it will not alter the passed pointer.

You need to pass the address of the pointer in order to be able to alter it, like this

// Change the pointer of the array
void change(int **array, int length)
{
*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}

Then in main() you cannot assign to an array, doing so through this kind of function is surely undefined behavior. The array defined in main() is allocated on the stack and you cannot assign anything to an array since they are non-writeable lvalues so you cannot make it point to a heap memory location obtained with malloc(), you need to pass a pointer like this

int *array;
change(&array, length);
free(array);

If you want the function to replace the previous array, it will have to free() the malloc()ed data (note that passing NULL to free() is well defined), so

// Change the pointer of the array
void change(int **array, int length)
{
free(*array);

*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}

then in main()

int *array;
array = NULL;
change(&array, length);
change(&array, length);
change(&array, length);
change(&array, length);
free(array);

will do what you apparently want.

How to modify an array inside a function in C

Consider your first program.

#include <stdio.h>

void change_byte(int *byte);

int main()
{
int byte = 0;
change_byte(&byte);
printf("Byte : %d \r\n", byte);
}

void change_byte(int *byte)
{
*byte= 5;
}

In this program the object byte is passed to the function change_byte by reference through a pointer to it

change_byte(&byte);

In C passing by reference means passing an object indirectly through a pointer tp it.

So dereferencing the pointer byte declared as a function parameter

void change_byte(int *byte);

you get a direct access to the pointed object byte of the type int defined in main.

Now let's consider your second program

#include <stdio.h>
#define SIZE_ARRAY 10

void change_array(int *array, int size);

int main()
{
int array[SIZE_ARRAY] = {0};
change_array(array, SIZE_ARRAY);

printf("Array : ");
for(int i = 0 ; i < SIZE_ARRAY ; i++)
{
printf("%d ", array[i]);
}
}

void change_array(int *array, int size)
{
for(int i = 0 ; i < size ; i++)
{
array[i] = 5;
}
}

In main you declared an integer array

int array[SIZE_ARRAY] = {0};

Array designators used in expressions with rare exceptions are converted to pointers to their first elements.

Thus this call

change_array(array, SIZE_ARRAY);

is equivalent to

change_array( &array[0], SIZE_ARRAY);

So dereferencing the pointer within the function you can change the first element of the array defined in main.

But array elements are stored in a continuous extent of memory. So using the pointer arithmetic and having a pointer to the first element of an array you can access all elements of the array.

In fact all elements of the array array are passed to the function change_array by reference through a pointer to the first element of the array.

For example the for loop within the function you could rewrite like

    for(int i = 0 ; i < size ; i++)
{
*( array + i ) = 5;
}

Now let's consider your third program.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array(int *array, int size);

int main()
{
int array[SIZE_ARRAY] = {0};
change_array(array, SIZE_ARRAY);

printf("Array : ");
for(int i = 0 ; i < SIZE_ARRAY ; i++)
{
printf("%d ", array[i]);
}
}

void change_array(int *array, int size)
{
array = global_array;
}

As it was pointed out already the array array passed to the function change_array is converted to a pointer to its first element.

You may imagine the function call and its definition the following way (I will rename the first function parameter that to avoid name ambiguity).

change_array(array, SIZE_ARRAY);

//...

void change_array( /* int *parm_array, int size */)
{
int * parm_array = array;
int size = SIZE_ARRAY;

parm_array = global_array;
}

That is function parameters are its local variables. The parameter parm_array is alive until the function stops its execution.

Thus this statement

    parm_array = global_array;

assign the pointer to the first element of the global array global_array to the local variable parm_array of the function. This assignment does not touch in any way the array array defined in main. It only changes the local variable parm_array declared in the function change_array.

To achieve the expected by you result you could define in main a pointer that is initialized by the array array. And in the function change_array you could reassigned the pointer with the array global_array passing it to the function by reference the same way as you passed the object byte in your first program.

Here is a demonstrative program.

#include <stdio.h>
#define SIZE_ARRAY 10

int global_array[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};

void change_array( int **array_ptr );

int main()
{
int array[SIZE_ARRAY] = {0};
int *array_ptr = array;

change_array( &array_ptr );

printf("Array : ");
for(int i = 0 ; i < SIZE_ARRAY ; i++)
{
printf("%d ", array_ptr[i]);
}
}

void change_array( int **array_ptr )
{
*array_ptr = global_array;
}

The program output is'

Array : 5 5 5 5 5 5 5 5 5 5 

Modifying array inside a function in C

This might make more sense for you if you think of & as an operator which acts on a single item, much like - acts on a number to change the sign. In this case, & takes the address of whatever you give it. In the case of &a[0], you are taking the address of a[0]. In the case of &a[1], you take the address of a[1]. In other words, you take the address of different elements of the array. So in the function, b contains the address that you passed to it. As far as the function knows, what you pass in is the "first" element of the array. It knows nothing of any of the preceding elements.

How to edit an array in another function than the main function in c programming?

There you go. I suppose this is what you want:

#include <stdio.h>

// Since the array named parameters are scoped only within its function,
// they are apart from your array in the main.
void function(int array[], int len) {

int i = 0;
while(i<len) {
array[i]=array[i]+1;
i++;
}
}

// Or alternatively you can process the array using a pointer
void functionWithPointer(int *array, int len) {

int i = 0;
while(i<len) {
*(array+i) = *(array+i)+1;
i++;
}
}

int main() {
int array[]={1,2,3,4,5};
// int answer; // Not necessary
int length = sizeof(array) / sizeof(int); // !!!ATTENTION

function(array, length);

// The array values updated by 1
printf("Array values after 1st update\n");
for(int k=0; k<length; k++) {
printf("%d \n",array[k]);
}

functionWithPointer(array, length);

// The array values updated by 1 again
printf("Array values after 2nd update\n");
int j;
while(j<length) {
printf("%d \n",array[j]);
j++;
}

return 0;
}

Here is the output:

Array values after 1st update
2
3
4
5
6
Array values after 2nd update
3
4
5
6
7

How can I pass an array to a function that cannot modify it?

First, the declarations const Foo array_in[] and Foo const array_in[] are exactly the same in C.

Second, when the parameter type of a function has "array of T" type, it is automatically adjusted to "pointer to T" type. So the compiler pretends as if you wrote:

void func(const Foo *array_in)

or equivalently

void func(Foo const *array_in)

Note that both const Foo *array_in and Foo const *array_in mean the exact same thing in C (pointer to const Foo). However, Foo * const array_in means something different (const pointer to Foo).

Trying to modify array in function in C

You're not telling us what the error or problem is, but I can make an educated guess:

read_array(array[10]);

should be just

read_array(array);

Beyond that, though, read_array() should preferably also take a maximum size argument, because otherwise it has no way of knowing the size of the array. For your program, it does happen to always be 10. Something like this:

/**
Read up to `n` integers from `array.txt` into the array `arr`,
returning the count that was successfully read.
*/
int read_array(int *arr, int n) {
FILE *fp;
int var;
int i;
fp = fopen("array.txt", "r");
for (i = 0; i < n; i++) {
if(fscanf(fp, "%d", &var) < 1) { // < 1 means EOF or scan failed
break;
}
arr[i] = var;
}
fclose(fp);
return i;
}


Related Topics



Leave a reply



Submit