It cannot work (even theoretically), because arrays are not pointers:


  • int arr[10]:

    • Amount of memory used is sizeof(int)*10 bytes

    • The values of arr and &arr are necessarily identical

    • arr points to a valid memory address, but cannot be set to point to another memory address


  • int* ptr = malloc(sizeof(int)*10):

    • Amount of memory used is sizeof(int*) + sizeof(int)*10 bytes

    • The values of ptr and &ptr are not necessarily identical (in fact, they are mostly different)

    • ptr can be set to point to both valid and invalid memory addresses, as many times as you will

Answer from barak manos on Stack Overflow
Discussions

Changing the base address of an array !!
Is the correct output in Approach 2, is a kind of undefined behaviour that gives correct output ? AFAIK, the base address manipulation is not possible in C language and the compiler does not allow to do it. But, the output from the approach 2, seems to convey a different info. Strange !! Any ideas ? Thx in advans, Karthik Balaguru ... Hi, I got an interesting output w.r.t array ... More on thecodingforums.com
๐ŸŒ thecodingforums.com
8
March 16, 2009
How to change array's variables by address in C? - Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I'm trying to change array's variables address by swapping the address, ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Changing array inside function in C - Stack Overflow
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 ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
c - Why cannot we change the base address of an array - Stack Overflow
Whereas arr is literally the address in the memory which only decays like &arr[0] when used as Rvalue. ... complier throws error as Expression must be a modifiable lvalue As the arr is allocated on the stack we cannot change the address because we are asking cpu to change the address of the array, ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Top answer
1 of 2
1

First, recognize that you are passing addresses instead of integer values to printf_s. Take a look at the warning messages issued by the compiler. In particular, note the types of the arguments that the compiler is warning about. To determine the addresses passed to the function, the compiler is doing address arithmetic based on the type of the address. In calculating the address of &arr+1 the compiler starts by taking the address of the array. The compiler looks at the type of the argument and determines that size of the int (*)[5] type is 20. So it adds 20 to the starting address of the array.

Look at the difference in the warning messages and the result of using the following -

 printf_s("%u %u\n", arr + 1, (int*) &arr + 1);
2 of 2
1

Your assumption that arr and &arr are the same is incorrect. While they happen to point to the same location in memory, they have completely different types.

In most contexts, an expression with type array of T is automatically converted to pointer to first array element. So the expression arr is treated as if you had coded &arr[0].

An exception to this conversion is when the expression is the operand of the & operator. In this case, no conversion is performed.

Pointer arithmetic is always performed with an implicit scaling based on the size of the object type pointed to. On your system, an int is 4 bytes. So arr+1 points to a location just past the end of arr[0] which is four bytes away. &arr+1 points to a location just past the end of arr which is 20 bytes away.

Also note that for the call to printf to be well defined, you should cast the values to void* and use %p as the format. While it often will work as you coded it, you should use the correct method to avoid problems when it doesn't,

๐ŸŒ
The Coding Forums
thecodingforums.com โ€บ archive โ€บ archive โ€บ c programming
Changing the base address of an array !! | C Programming | Coding Forums
March 16, 2009 - In other words, the above declaration is exactly equivalent to: void incre(char *a) Now, when you call eincre() in main() with 'a' as an argument, it is automatically converted into a pointer to the first element of the array named 'a'. As before, that pointer is not an lvalue, and it cannot be changed.
๐ŸŒ
Zhu45
zhu45.org โ€บ posts โ€บ 2017 โ€บ Jan โ€บ 08 โ€บ modify-array-inside-function-in-c
Modify array inside function in C - Zeyuan Hu's Page
In general, there are two cases ... a look at the following sample function first: void change(int *array,int length) { printf("array address inside function: %p\n", array); int i; for(i = 0 ; i < length ; i++) array[i] = 5; }...
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 71375288 โ€บ how-to-change-arrays-variables-by-address-in-c
How to change array's variables by address in C? - Stack Overflow
As you have shown in the image, the addresses of the array elements are all contiguous and differ by just 4 bytes. You are able to say for example a = a + 20 which causes a[0] to point to a[5], but then the rest of the array elements are also shifted and will point to after that as explained above. Technically, you can only change where the beginning of the array points to, and you are not able to change where the middle of the array points to.
Top answer
1 of 10
31

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.

2 of 10
3

Ok, i will make the answer short.

  1. Arrays are always passed by reference in C

change(array, length); In this line, it means reference to the first element of the array variable is passed to the function.

Now the function needs a pointer to catch the reference, it can be a pointer or it can be an array. Note that the pointer or the array is local to the function.

  1. You received it in a pointer named array. Which is definitely a pointer but it is not the same as array in main function. It is local to the change function.

  2. You declared a new array dynamically, and assigned a pointer named new with it. And all the changes you did were to new pointer.

Everything is ok till now.

  1. Now you assigned the new pointer to the array pointer which is local to the change function.

This is the real issue. As even though the array is in heap section, and it will remain in the memory, but the *array and *new are local pointer variables.

Also array pointer in change function is different from array pointer in main function.

  1. The solution to this problem is Manipulate the data of array pointer directly.

    void change(int *array,int length) { int i; for(i = 0 ; i < length ; i++) array[i] = 1; }

In this way you are directly overwriting values of array in main function. Everything else is correct.

Summerization: array pointer in change function is local to change function. array in main function is local to main function. Making change function's local array pointer point to array in heap section won't change data in actual array. You changed pointer's position, Not the array's data.

Top answer
1 of 2
1

arr is not a pointer, it's an array. When you use the word arr the compiler may convert it to a pointer for you - it does &arr[0] automatically, and gets the address of the first element, which is a pointer value, not a pointer variable. And you can't change values. You can't do (&some_variable)++;, you can't do 5++;, and you can't do (&arr[0])++; which is what arr++; would mean.

2 of 2
0

Arrays are not pointers.

Consider the following demonstrative program.

#include <stdio.h>

int main(void) 
{
    int arr[3] = { 1, 2, 3 };
    int *p = arr;
    
    printf( "sizeof( arr ) = %zu\n", sizeof( arr ) );
    printf( "sizeof( p ) = %zu\n", sizeof( p ) );
    
    return 0;
}

Its output might look like

sizeof( arr ) = 12
sizeof( p ) = 8

Arrays are non-modifiable lvalues. That means that you for example can not assign one array to another or apply an increment operator.

On the other hand, arrays used in expressions are implicitly converted (with rare exceptions) to pointers to their first elements.

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type โ€˜โ€˜array of typeโ€™โ€™ is converted to an expression with type โ€˜โ€˜pointer to typeโ€™โ€™ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

So for example in this declaration

int *p = arr;

the array arr used as an initializer expression is implicitly converted to pointer to its first element that has the type int *.

To set the pointer p to point to the second element of the array arr you could use the pointer arithmetic the following way

int *p = arr + 1;
Find elsewhere
๐ŸŒ
Cprogramming
cboard.cprogramming.com โ€บ c-programming โ€บ 108081-changing-address-pointer-question.html
changing the address of a pointer question..
... this is a quote from an article: " int foo; int *foo_ptr = &foo; Now, how do you assign an int to this pointer? This solution might be obvious: foo_ptr = 42; It is also wrong. Any direct assignment to a pointer variable will change the address in the variable, not the value at that address.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ dsa โ€บ can-you-assign-a-different-address-to-an-array-tag
Can you assign a different address to an Array tag ? - GeeksforGeeks
July 23, 2025 - On retrieval, if specify only the ... with the array tag. However, you can use a pointer variable to point to the array, and then assign a different address to the pointer variable. This would change the address ....
Top answer
1 of 3
1

I have a char ** array that has 3 pointers

No, you don't. You have an array with three values. The values happen to be pointers. An array doesn't have pointers.

Suppose you allocate memory for this array (of pointers to char):

char **array = malloc( 3 * sizeof(char*)); // 3 values in the array

and then you allocate memory for each string:

array[0] = malloc(4 * sizeof(char) ); // 3 + 1 null terminator
array[1] = malloc(4 * sizeof(char) );
array[2] = 0;

finally you set the values for the strings themselves:

strcpy( array[0], "abc" );
strcpy( array[1], "def" );

Now you want to make a copy. A deep copy actually, because you not only allocate memory for a new array (of pointers to char) but you allocate memory for new strings as well. You do exactly the same allocation:

char **array2 = malloc( 3 * sizeof(char*));
array2[0] = malloc(4 * sizeof(char) );
array2[1] = malloc(4 * sizeof(char) );
array2[2] = 0;

Now you copy the actual strings:

strcpy( array2[0], array[0] );
strcpy( array2[1], array[1] );

If your code differs from the one above, edit your question with more details.

The tricky part is making array[0] hold the address which is in array2[0] (same for array[1] and array2[1]). The problem comes from the fact that memory you allocate via malloc needs to be freed via free.

So you can't just do

array[0] = array2[0];

Because you've lost all references to the first string you allocated. That memory is leaked.

Instead do this:

free(array[0]);
array[0] = array2[0];

This frees the memory used for the first string and copies the address of the copy.

Now you have the same pointer (value) in two variables. This is also tricky because (when you no longer need it) you still need to free the memory allocated for the copy:

free(array2[0])

The tricky part is that array[0] now holds a pointer to freed memory, which can't be used. Using it will lead to bugs.

It would probably be a good idea not to have multiple variables (in the same scope) that hold the same pointer to allocated memory. That may make it difficult to reason about the validity of the pointer.

2 of 3
0

char ** array is a pointer of pointers. In this case, it gets assigned an array of char pointers, each of which contains the address of the first char of your eventual cstrings.

As such, you can just use the equal sign, as you would with an other regular pointer:

array[0] = (char*)0x7ffffffc;

array[1] = (char*)0x80033d;

๐ŸŒ
Study.com
study.com โ€บ courses โ€บ computer science courses โ€บ computer science 111: programming in c
Passing & Using Array Addresses in C Programming | Study.com
The asterisk in front of the variable means that b is a pointer. This means that b's value actually points to the address of another variable. When we use it, it will point to the batters array, and we can then change that underlying array.
๐ŸŒ
Quora
quora.com โ€บ How-do-you-pass-the-address-of-an-array-in-C
How to pass the address of an array in C - Quora
The array name turns into a typed pointer to the first byte of the array when passed in. The value of the pointer A (contains the address of the array in RAM) is copied into the pointer that is the parameter, in this case arr. The memory in RAM now has a handle inside the function as arr, so changing the values in memory using it will now work.
๐ŸŒ
Northern Illinois University
faculty.cs.niu.edu โ€บ ~mcmahon โ€บ CS241 โ€บ Notes โ€บ arrays_and_pointers.html
Arrays and Pointers
As mentioned above, passing an unsubscripted array name as an argument to a function converts the array name into to a pointer to the first element of the array. That means the array is passed by address, which means the function it is passed to can change the values stored in the original array.
๐ŸŒ
Quora
quora.com โ€บ How-do-I-assign-an-array-to-a-specific-memory-address-in-C
How to assign an array to a specific memory address in C - Quora
Define a section in the linker script with fixed address: SECTIONS { .my_array 0x20001000 : { KEEP(*(.my_array)) } } ... Or specify absolute address with assembly label or via linker SYMBOL = ADDRESS and extern reference. Use volatile for MMIO or shared memory regions. This is the correct way to place statically allocated objects at fixed addresses. ... Map the physical address to virtual memory in user space (POSIX) or access directly in kernel/firmware: ... Requires privileges and careful page-aligned offsets.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ changing-array-inside-function-in-c
Changing Array Inside Function in C - GeeksforGeeks
July 23, 2025 - When declaring an array the array name is always called the pointer because in an array name the address of the 0th block(base address) is stored. To change an array in the function we have to pass an array in the function.
๐ŸŒ
HowStuffWorks
computer.howstuffworks.com โ€บ tech โ€บ computer software โ€บ programming
Using Pointers with Arrays - The Basics of C Programming | HowStuffWorks
March 8, 2023 - Instead they are permanent pointers to arrays. a and b permanently point to the first elements of their respective arrays -- they hold the addresses of a[0] and b[0] respectively. Since they are permanent pointers you cannot change their addresses.
๐ŸŒ
Reddit
reddit.com โ€บ r/c_programming โ€บ placing array at specific memory address seems to not work
r/C_Programming on Reddit: Placing array at specific memory address seems to not work
October 6, 2021 -

I am dealing with a block of memory. I get the address of the block, and I store two 1 byte variables, and then a 2x8x8 1 byte array right after. I use pointers to access the variables easily.

However, when I get the addresses of the variables I notice something weird. The individual variables are 1 address from each other as expected. However, the array seems to be located 7 addresses from the last variable instead of 1 address like I expected. What is going wrong?

volatile unsigned int* address = get_address();
volatile uint8_t* var1 = (volatile uint8_t*) (address);
volatile uint8_t* var2 = (volatile uint8_t*) (address+1);
volatile uint8_t (*array1)[2][8][8] = (volatile uint8_t*) (address+2);
volatile uint8_t (*array2)[2][8][8] = (volatile uint8_t*) (address+3+2*8*8);

printf("var 1 address: %u\n",var1); // var 1 address: 3067375616
printf("var 2 address: %u\n",var2); // var 2 address: 3067375617
printf("array 1 address: %u\n",&(*array1)[0][0][0]); // array 1 address: 3067375624
printf("array 2 address: %u\n",&(*array2)[0][0][0]); // array 2 address: 3067376140

Edit: I figured it out! I believe the problem was the order I was casting. To simplify things, I just changed the type of address to uint8_t* and did away with casting all together

Top answer
1 of 5
4
I can't find an obvious problem but this may be due to an operator precedence issue. The casting operator takes higher precedence than the arithmetic operators, so doing (T*)ptr+2 actually means ((T*)ptr) + 2 so if sizeof(T) is greater than 1 you'll actually be adding 2 * sizeof(T) to your address. In this case I don't see that being an issue directly since sizeof(uint8_t) is 1, but I wonder if this issue is still somehow related. Use a debugger and inspect the addresses and arithmetic directly and see what's going on.
2 of 5
3
Whatever you are trying to do, this isn't the way to do it I'm afraid. I'll get onto a better solution below. However, it seems to work on my machine (64-bit Linux using gcc): var 1 address: 3067375616 var 2 address: 3067375617 array 1 address: 3067375618 array 2 address: 3067375747 So why is this the wrong way to do things? You're trying to use explicit addresses with hardcoded offsets to store stuff in - it is just asking for trouble further down the road and will be a maintenance headache. There are two (or maybe more) 'correct' ways to do this: Packing/unpacking - you would unpack the data from the specific address into a structure locally, manipulate the data and packing it back to the specific address. Packed structure access - define a packed structure representing the structure of your data and then use a pointer to access it at the specific address. Here's an example of number 2: // data structure definition // __attribute__((packed)) is gcc compatible, other compilers may require typedef struct __attribute__((packed)) { uint8_t var1; uint8_t var2; uint8_t array1[2][8][8]; uint8_t array2[2][8][8]; } data_t; int main(void) { // assign a pointer 'p' of the above structure type but pointing at volatile data_t *p = (volatile data_t *)get_address(); printf("var 1 address: %lu\n",&p->var1); // var 1 address: 3067375616 printf("var 2 address: %lu\n",&p->var2); // var 2 address: 3067375617 printf("array 1 address: %lu\n",&p->array1[0][0][0]); // array 1 address: 3067375624 printf("array 2 address: %lu\n",&p->array2[0][0][0]); // array 2 address: 3067376140 return 0; } With this you've no hardcoded offsets and will continue to work when the structure changes. When it runs, the output is: var 1 address: 3067375616 var 2 address: 3067375617 array 1 address: 3067375618 array 2 address: 3067375746 And this points to a what I think is a bug in your original implementation: volatile uint8_t (*array2)[2][8][8] = (volatile uint8_t*) address+3+2*8*8; I think the '+3' is wrong and should be '+2'. Using the packed structure access allows direct access to the memory at a specific address whilst avoiding calculated offsets which are prone to human error. Of course, there could be a really good reason why you've chosen to do it this way and in which case I'd be interested to hear it. If this is an embedded system, even what I've written isn't the right way to access memory at a specific location, the right way would be to still use the structure but place an instance of the structure in a specific linker section that is assigned to that address at link time. Edits: code blocks didn't work, what did I do wrong?!