I will provide some concepts that will potentially help you derive a solution to your problem. Then provide a quick solution that can help you with your final solution.

...If I just assign a = b like this then I get the output 15, 9, 8, 4, 3, 5 with 5 being a garbage value.

The output of the number 5 has nothing to do with your assignment of a=b in fcn02. The value 5 is actually the value of x in the calling function. You are accessing the array outside the bounds of it's original allocation thus accessing the value of next address of the size of int. In this case it's the value of x. if you spit out the address of x and the address of a[6] you will see that they are equal.

Your assignment in fcn02 of a=b does not work as you intended due to the fundamental concept of passing values to a function. When you call the function fcn02(a) the value "a" (the address of the beginning of the array) is copied to the value of "a" in fcn02. Changing "a" in fcn02 does not change "a" in the calling function.

Example for clarification NOTE( Using the same value "a" can be confusing so I changed it a bit).:

int func02( int* b ) // address of a is copied to b
{

     ... // some code...c is dynamically allocated and has an address of 0x80004d30
     b = c;  // b is set to address of c; thus, b address is now 0x80004d30
     // a is unchanged and you now have a memory leak since you didn't delete b.
}

int main()
{
    int a[5] = {1,2,3,4}; // address is 0x28cc58
    func02(a);  // complier will make a copy of the value of a to b
    // address (i.e. value) of a is still 0x28cc58
 
}

Memory layout of why you see 5:

int a[5] = {1,2,3,4,5};  // 0x28cc64 
int x = 7;               // 0x28cc5c

{    array a            }{ x  }
 ---- ---- ---- ---- ---- ---- 
| 1  | 2  | 3  | 4  | 5  | 7  | 
 ---- ---- ---- ---- ---- ----

However to answer you question you can NOT assign one array to another.

int a[5] = {1,2,3,4,5};
int b[5];
b = a;
for ( int i = 0; i<5; ++i )
{
     cout << b[i] << endl;
}

The compiler will not allow this.

Here is quick and dirty solution keeping your function parameters the same for guidance:

void e02(){
    int a[6] = {15, 9, 8, 4, 3, 0};
    int sizeofA = 5;
    int numToAdd = 5;

    fn02(a, sizeofA, numToAdd);
    cout << endl;

    for(int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
}

void fn02(int* a, int &n, int x) {
    n += 1;
    int i = 0;

    while( i < n ) {
        if ( a[i] > x ) {
            ++i;
        }
        else {
            int tmp = a[i];
            a[i] = x;
            x = tmp;
        }
    }
}
Answer from Carlos on Stack Overflow
Top answer
1 of 2
3

I will provide some concepts that will potentially help you derive a solution to your problem. Then provide a quick solution that can help you with your final solution.

...If I just assign a = b like this then I get the output 15, 9, 8, 4, 3, 5 with 5 being a garbage value.

The output of the number 5 has nothing to do with your assignment of a=b in fcn02. The value 5 is actually the value of x in the calling function. You are accessing the array outside the bounds of it's original allocation thus accessing the value of next address of the size of int. In this case it's the value of x. if you spit out the address of x and the address of a[6] you will see that they are equal.

Your assignment in fcn02 of a=b does not work as you intended due to the fundamental concept of passing values to a function. When you call the function fcn02(a) the value "a" (the address of the beginning of the array) is copied to the value of "a" in fcn02. Changing "a" in fcn02 does not change "a" in the calling function.

Example for clarification NOTE( Using the same value "a" can be confusing so I changed it a bit).:

int func02( int* b ) // address of a is copied to b
{

     ... // some code...c is dynamically allocated and has an address of 0x80004d30
     b = c;  // b is set to address of c; thus, b address is now 0x80004d30
     // a is unchanged and you now have a memory leak since you didn't delete b.
}

int main()
{
    int a[5] = {1,2,3,4}; // address is 0x28cc58
    func02(a);  // complier will make a copy of the value of a to b
    // address (i.e. value) of a is still 0x28cc58
 
}

Memory layout of why you see 5:

int a[5] = {1,2,3,4,5};  // 0x28cc64 
int x = 7;               // 0x28cc5c

{    array a            }{ x  }
 ---- ---- ---- ---- ---- ---- 
| 1  | 2  | 3  | 4  | 5  | 7  | 
 ---- ---- ---- ---- ---- ----

However to answer you question you can NOT assign one array to another.

int a[5] = {1,2,3,4,5};
int b[5];
b = a;
for ( int i = 0; i<5; ++i )
{
     cout << b[i] << endl;
}

The compiler will not allow this.

Here is quick and dirty solution keeping your function parameters the same for guidance:

void e02(){
    int a[6] = {15, 9, 8, 4, 3, 0};
    int sizeofA = 5;
    int numToAdd = 5;

    fn02(a, sizeofA, numToAdd);
    cout << endl;

    for(int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
}

void fn02(int* a, int &n, int x) {
    n += 1;
    int i = 0;

    while( i < n ) {
        if ( a[i] > x ) {
            ++i;
        }
        else {
            int tmp = a[i];
            a[i] = x;
            x = tmp;
        }
    }
}
2 of 2
0

In order to insert an element in a sorted vector (decreasing order), you could try this:

#include <iostream>
#include <vector>
using namespace std;

void InsertItemInSortedArray(std::vector<int>& vec, int item)
{
    auto high_pos=std::lower_bound (vec.rbegin(), vec.rend(), item);
    vec.insert(high_pos.base(), item);
}

int main() {
    std::vector<int> vec = {15, 9, 8, 4, 3};
    int item = 5;
    InsertItemInSortedArray(vec, item);

    for (const auto& elem : vec) 
    {
        std::cout << elem << std::endl;
    }
    return 0;
}
🌐
Medium
medium.com › @muskaanembed2023 › why-cant-you-reassign-an-array-name-in-c-2ce355202a56
Why Can’t You Reassign an Array Name in C? | by Muskaan Jain | Medium
September 23, 2024 - It’s not like a pointer, where you can say “Hey, now point to this other thing.” Once you set it, the array name becomes a constant reference to that specific memory location. And C enforces this to maintain efficiency and predictable behavior. ... The real reason you can’t reassign an array name in C is because an array name is a constant reference to a specific block of memory.
Discussions

[Help] Why can't you assign an array to another array?
int b[]; This isn't even legal to begin with, since you didn't give a size for the array. But let's say you did: int a[3] = {0, 1, 2}; int b[3] = {0}; b = a; When you refer to an array's name in almost all contexts, you get a pointer to the array (equivalent to the address of its first element). So this is saying: &(b[0]) = &(a[0]); which is obviously nonsensical, you can't change the address of b[0]. This works: int *b; b = a; because it becomes: b = &(a[0]); and b is a thing you can assign an int* to. They could allow this in contexts where the size of both arrays is known, and make it a shorthand for something like: for (int i = 0; i < min(sizeof(a)/sizeof(a[0]), sizeof(b)/sizeof(b[0])); i++) { b[i] = a[i]; } but the people who created C didn't do that. And because they decay into pointers whenever you pass them anywhere it isn't all that useful. This does work with std::array in C++, since the size information is part of the type and is maintained when you pass references/pointers to such arrays. More on reddit.com
🌐 r/C_Programming
9
2
November 1, 2021
C array declaration and assignment? - Stack Overflow
I've asked a similar question on structs here but I'm trying to figure out how C handles things like assigning variables and why it isn't allowed to assign them to eachother if they are functionall... More on stackoverflow.com
🌐 stackoverflow.com
Changing array inside function in C - Stack Overflow
Array is a local variable inside both main and change. Its address is passed from main to change. After that, change can reassign it and it will have no effect on the array in main. The two variables are unrelated. More on stackoverflow.com
🌐 stackoverflow.com
pointers - How to reassign value of element of char array in C - Stack Overflow
I would like to change the value of the third letter in apple to "a". Using the indirection this way gives me a compiler error saying: invalid type argument of unary ‘*’ (have ‘int’) #include More on stackoverflow.com
🌐 stackoverflow.com
May 24, 2017
🌐
Reddit
reddit.com › r/c_programming › [help] why can't you assign an array to another array?
r/C_Programming on Reddit: [Help] Why can't you assign an array to another array?
November 1, 2021 -

The following code snippet has an error error: invalid initializer:

int main() {
  int a[3] = {0, 1, 2};
  int b[3];
  b = a;
  return 0;
}

There were some StackOverflow answers regarding this, but I still have some questions about it.

 

My Understanding

There is the mantra that "arrays decay into pointers", but I'm aware that does not mean that arrays are equivalent to pointers.

Here,

int main() {
  int *p = malloc(3 * sizeof(int));
  for (int i = 0; i < 3; i++)
    p[i] = i;
}

The compiler will allocate a pointer's worth of memory to p, and the value of p is the address of some location on the heap. In the top code snippet, the compiler allocates 3 ints worth of memory and the value of a is that entire block of memory.

So for me, the above code snippet is similar to declaring an int. When declaring some int i, the compiler allocates an int's worth of memory for i and i's value is that block of memory.

And for an int, this would compile just fine:

int main() {
  int x = 5;
  int y;
  y = x;
  return 0;
}

I don't see why the compiler couldn't just take the data stored at a and copy that over to b, just like how it does above.

 


 

I also started messing around with the code some more, and I noticed that this worked for some reason:

int main() {
  int a[3] = {1, 2, 3};
  int *b;
  b = a;
  return 0;
}

What's the difference here?


EDIT: fixed typos

Top answer
1 of 5
6
int b[]; This isn't even legal to begin with, since you didn't give a size for the array. But let's say you did: int a[3] = {0, 1, 2}; int b[3] = {0}; b = a; When you refer to an array's name in almost all contexts, you get a pointer to the array (equivalent to the address of its first element). So this is saying: &(b[0]) = &(a[0]); which is obviously nonsensical, you can't change the address of b[0]. This works: int *b; b = a; because it becomes: b = &(a[0]); and b is a thing you can assign an int* to. They could allow this in contexts where the size of both arrays is known, and make it a shorthand for something like: for (int i = 0; i < min(sizeof(a)/sizeof(a[0]), sizeof(b)/sizeof(b[0])); i++) { b[i] = a[i]; } but the people who created C didn't do that. And because they decay into pointers whenever you pass them anywhere it isn't all that useful. This does work with std::array in C++, since the size information is part of the type and is maintained when you pass references/pointers to such arrays.
2 of 5
2
I don't see why the compiler couldn't just take the data stored at a and copy that over to b, just like how it does above. There's no reason why a language can't do that. My private systems language can do this: []int a := (10, 20, 30) # 3-element array (note int is int64) [a.len]int b # prepare b of same size b := a # copies 3 elements or 24 bytes If I get it to transpile to C, that assignment gets turned into this line of C: memcpy(&b, &a, 24); This is because my language manipulates arrays by value; C doesn't do that. As soon as an array value, say 'a', threatens to appear in an expression, it gets converted to a pointer, the equivalent of treating it as &a[0]. Your last example in C: int* b; b = a; Is really just: b = &a[0]; b is now a pointer location; this sets b to the address of a's first element. There are some advantages to how C does things; manipulating arrays by pointer is more efficient, and not having to write &a[0] everywhere leads to cleaner code. However it can also get confusing. And notice that the pointer produced is not to the whole array (ie. &a), but to the first element, which has type int* not (int(*)[]), which leads to a whole bunch of other issues. But it is what it is ...
🌐
Zhu45
zhu45.org › posts › 2017 › Jan › 08 › modify-array-inside-function-in-c
Modify array inside function in C - Zeyuan Hu's Page
However, this is wrong and the output confirms our observation above: array is local variable to the caller function and callee function, and when we pass a array into a function, the address is passed (copied) from caller to callee. After that, address inside callee can reassign and will have no effect on the array (address) in caller.
Find elsewhere
🌐
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.
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.

🌐
Bytes
bytes.com › home › forum › topic
assigning values to an array after declaring it - C / C++
November 14, 2005 - I can't assign values immediately on declaration because I want myarray to be initialised differently according to various cases only determined at runtime. Thanks for any help. best regards -Eric ... Re: assigning values to an array after declaring it Eric Bantock wrote:[color=blue] > Very ...
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 161906-make-array-point-another-array.html
make an array to point to another array
If you truly just want to point to the same memory in your string array from a separate array, you can do so by 'char *' variable_name '[x];' and then by copying the references to strings from your initial array.
🌐
Microsoft
social.msdn.microsoft.com › Forums › en-US › f2013e5e-0927-42d2-8737-a84c5d737e14 › how-to-quotreassignquot-a-character-string-to-an-existing-char-array
How to "re-assign" a character string to an existing char array? | Microsoft Learn
September 15, 2021 - b) assign 0 to first array element: ... the initial assignment, to reassign C style string you have to copy the characters to the array one element at a time....
Top answer
1 of 2
1

Well, when you do

double s[3]={1,2,3};

That memory is not managed by you, so you can not free it. You can only use free when you allocate memory using malloc or calloc (i.e. dynamically allocated memory). Additionally, you have a memory leak there because

ptr=(double*)malloc(sizeof(double)*3); // here you allocate memory 
...
ptr = s; // here you change the pointer address but allocated memory is never freed

a solution would be to use a for loop to copy the values from s to ptr, and do the same in changePtr to copy values from s1 to ptr.

2 of 2
1

Edit 1

To your original question:

Short answer: Yes, you can reassign a pointer to a smaller array in C.

Long answer: The short answer is misleading. Arrays are also simply pointers in C. And for a better understanding of this concept, you might want to read this thread, especially take a look at this answer.


The problem is that you try to de-allocate the memory on stack.

Whenever you create a local variable, à la int a = 5, it's pushed on the stack, that is this variable gets memory allocated on stack and after the function call (main()) is over the memory is de-allocated - all this happens automatically!

In your case, here is what happens:

// memory is allocated automatically on stack for the local variable "s"
double s[3]={1,2,3};

// assign the stack address of "s" to "ptr"
ptr = s;

// de-allocate the managed stack address of "s", which is NOT allowed!
free(ptr);

Creating dynamic memory, e.g. via malloc, on the other hand happens in the heap memory, which needs to be managed by the programmer, that is allocating (malloc()) and de-allocating (free()) memory is allowed and must be done with great care.

So, in your programm when it hits this line free(ptr);, the assertion fails, because the target memory address doesn't meet the requirement -> IsValidHeapPointer: No ptr is not a valid heap pointer, because it holds the stack address of the s variable at that point. :)


Edit 2

I get garbage values like -1456815990147....1 when I print out the values of ptr after calling changePtr. Why is this?

It's because, you free the memory of ptr in changePtr(ptr) first, that is the content of ptr is written with some "garbage" value.

And then here you allocate new memory and assign it to ptr:

ptr = (double *) malloc(sizeof(double) * 2); 

After this point, the changes you make via ptr (i.e. ptr[i] = 12) has no influence on the previous address which ptr held. So, simply remove the free(ptr) and the above line, you don't need them.


Edit 3

So does ptr now only contain 2 values, right? After I delete that line you mentioned, and then printed out the values in ptr, it shows the correct values for ptr[0] and ptr[1] and then a garbage value for ptr[2].

Correct. ptr[2] is freed before, so unless you assign a new value to that address, it will remain a garbage. Also be careful after you have freed heap memory. You should not use the pointer to access memory or assign a new value to it. Consider your pointer "void" after you call free on it.

When I tried to print the size of it with printf("%d", sizeof(ptr)), it shows 8 and printf("%d", sizeof(ptr)/sizeof(ptr[0]) shows 1.

ptr is a pointer. sizeof(ptr) returns 8 bytes, that's the size of address that a pointer in your system holds. So, it is not the size of array... Further, determining the size of a pointer (which points to an array and passed to a function as reference - like you did changePtr(ptr)) during the runtime is programmatically not possible, you have to explicitly pass the array size to a function, if you want to do some loop operations.

🌐
Quora
quora.com › How-do-I-assign-a-value-to-the-elements-of-an-already-existing-array-using-a-function-in-C
How to assign a value to the elements of an already existing array using a function in C++ - Quora
You can go randomly to any specific position of an array and get or put a value to the corresponding cell. Second, actions in any language are performed inside a function or method, and C++ is not an exception.
🌐
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 - It is not possible to assign a different address to an array tag. We cannot assign an assignment operator to the Array Tag of that object. It can be achieved only with a pointer.
🌐
Cplusplus
cplusplus.com › forum › general › 104519
Changing Array Values - C++ Forum
Your val array has two dimensions, i.e. it is an array of arrays. For example: So, you have a choice. You can change line 17 to something similar to the above example or use val[NUMROWS*NUMCOLS], so you can use just one pair of brackets. To display all of the contents in the array, you should replace that 0 on line 24 with i and that i afterward with j.
🌐
Reddit
reddit.com › r/c_programming › can’t assign arrays
r/C_Programming on Reddit: Can’t assign arrays
July 4, 2023 -

This should be a valid code as taken from CS50:

// Copy string into memory, including '\0'
    for (int i = 0; i <= strlen(s); i++)
    {
        t[i] = s[i];
    }

But in other places (for instance https://www.reddit.com/r/C_Programming/comments/14oolus/comment/jqexig6/?utm_source=share&utm_medium=web2x&context=3), I have read that arrays cannot be assigned values this way. Must be missing something for sure.

🌐
Quora
quora.com › How-can-I-change-the-values-of-an-array-with-a-void-function-in-c
How to change the values of an array with a void function in c - Quora
Answer (1 of 6): There are two ways. 1. Suppose if the array is declared as global. You could simply change the values of array by assignment. 2. If the array your are talking about is not declared as global then pass the address of the array. To do that use & operator. Eg foo(&myarray). Once yo...
Top answer
1 of 5
13

"I know arrays are lvalues and are not assignable but in this case, all the compiler has to do is reassign a pointer."

"b should just point to the address of a. Why isn't this doable?"

You seem to confuse here something. b isn't a pointer. It is an array of three int elements.

b = a;

Since b is used here as lvalue in the assignment, it is taken as of type int [3], not int *. The pointer to decay rule takes no place in here for b, only for a as rvalue.

You cannot assign an array (here b) by a pointer to the first element of another array (here a) by using b = a; in C.

The syntax doesn't allow that.

That's what the error

"array type 'int [3]' is not assignable"

is saying to you for b.

Also you seem to be under the misunderstanding that the pointer to decay rule means that an array is anyhow converted to a pointer object, which can in any manner store addresses of locations of different objects.

This is not true. This conversion is only happening in a very implicit kind of way and is subject of this SO question:

Is the array to pointer decay changed to a pointer object?


If you want to assign the values from array a to the array b, you can use memcpy():

memcpy(b, a, sizeof(a));
2 of 5
8

I know arrays are lvalues and are not assignable but in this case, all the compiler has to do is reassign a pointer. b should just point to the address of a. Why isn't this doable?

Because b isn't a pointer. When you declare and allocate a and b, this is what you get:

+---+
| 1 | a[0]
+---+
| 2 | a[1]
+---+
| 3 | a[2]
+---+
 ...
+---+
| 4 | b[0]
+---+
| 5 | b[1]
+---+
| 6 | b[2]
+---+

No space is set aside for any pointers. There is no pointer object a or b separate from the array elements themselves.

C was derived from an earlier language called B, and in B there was a separate pointer to the first element:

   +---+
b: | +-+--+
   +---+  |
    ...   |
     +----+
     |
     V
   +---+
   |   | b[0]
   +---+
   |   | b[1]
   +---+
    ...
   +---+
   |   | b[N-1]
   +---+

When Dennis Ritchie was developing C, he wanted to keep B's array semantics (specifically, a[i] == *(a + i)), but he didn't want to store that separate pointer anywhere. So instead he created the following rule - unless it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T" and the value of the expression will be the address of the first element of the array, and that value is not an lvalue.

This has several practical effects, the most relevant here being that an array expression may not be the target of an assignment. Array expressions lose their "array-ness" under most circumstances, and simply are not treated like other types.

Edit

Actually, that misstates the case - array expression may not be the target of an assignment because an array expression is not a modifiable lvalue. The decay rule doesn't come into play. But the statement "arrays are not treated like other types" still holds.

End Edit

The upshot is that you cannot copy the contents of one array to the other using just the = operator. You must either use a library function like memcpy or copy each element individually.