Assignment to Expression with Array Type in C: Why It Fails
In C, an array is not a modifiable lvalue, so you cannot assign a new string or another array to it with = after declaration. Initialize the array when you declare it, copy elements into its existing storage, or use a pointer when you actually need to select a different string. This is a compile-time constraint, not a segmentation fault.
Quick Fix Summary
Use char name[16] = "Alice"; at declaration, or snprintf(name, sizeof name, "%s", source) afterward. Check the return value for failure or truncation. Only use strcpy when the destination is large enough for the source and its terminating null byte.

Why This Error Happens
Initialization is not assignment
char name[16] = "Alice"; initializes the array elements. The same text after a separate declaration, name = "Alice";, attempts array assignment and is invalid. An array owns contiguous element storage for its lifetime; it is not a pointer variable that can be redirected. Although array expressions commonly convert to a pointer to the first element, that conversion does not create an assignable array object.
Choose the operation that matches your data
For a C string, reserve room for the terminating \0. snprintf takes a capacity and writes at most capacity minus one characters when capacity is nonzero; a negative return means an encoding/output error, and a return greater than or equal to capacity means truncation. Use a literal format such as "%s" rather than treating user text as the format. strcpy copies through the terminator but has no capacity parameter: verify strlen(source) < capacity first. Neither function permits overlapping source and destination.
Numeric arrays and overlapping copies
memcpy(destination, source, sizeof destination) can copy a complete equal-sized numeric array when both ranges are valid and do not overlap. If they overlap, use memmove. Do not use strcpy for integer arrays or arbitrary binary data. Inside a function parameter declared char destination[], the parameter is adjusted to a pointer; sizeof destination measures that pointer, not the caller's buffer. Pass the capacity explicitly.
Pointer reassignment is a different design
const char *name = "Alice"; name = "Bob"; changes which string a pointer denotes. It does not copy characters. Do not write through a pointer to a string literal. For writable text use an actual character array or suitably allocated storage. A structure containing an array member can be assigned as a whole compatible structure; its array member still cannot be assigned separately.
Top Root Causes & Specific Code Fixes
String assigned after declaration
Move the literal into the initializer, or copy into the allocated buffer with an explicit capacity.
char name[16];
name = "Alice";char name[16] = "Alice";One numeric array assigned to another
Copy elements or a validated byte range. This fragment assumes both arrays are complete objects in the same scope and includes string.h.
int a[3] = {1, 2, 3};
int b[3];
b = a;int a[3] = {1, 2, 3};
int b[3];
memcpy(b, a, sizeof b);An array member treated as a pointer
Assign the entire structure when appropriate, or copy to the member after checking its capacity. Declaring a pointer instead changes ownership and lifetime responsibilities.
struct User { char name[16]; };
struct User u;
u.name = "Alice";struct User { char name[16]; };
struct User u = { .name = "Alice" };Complete Broken and Corrected Programs
Compare the source before running it. The broken program is intentionally incorrect; its behavior can depend on the compiler and platform.
Read the broken program
int main(void) {
char name[16];
name = "Alice";
return 0;
}Open broken program in compilerRead the corrected program
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char name[16];
const char *source = "Alice";
int needed = snprintf(name, sizeof name, "%s", source);
if (needed < 0 || (size_t)needed >= sizeof name) {
fputs("Name could not be copied completely\n", stderr);
return EXIT_FAILURE;
}
printf("Name: %s\n", name);
printf("Capacity: %zu bytes\n", sizeof name);
return EXIT_SUCCESS;
}Open corrected program in compilerExpected output from the corrected program
Reference output, not a live execution result.
Name: Alice
Capacity: 16 bytesDebugging Techniques and Commands
gcc -std=c17 -Wall -Wextra -Wpedantic main.c -o app
Fix the array assignment before investigating runtime behavior; this program cannot compile as written.
gcc -std=c17 -g -fsanitize=address,undefined main.c -o app
After fixing compilation, use sanitizers locally to exercise copy boundaries. Sanitizer availability depends on the compiler environment.
Frequently Asked Questions
Why can I initialize a char array but not assign a string later?
Initialization sets the elements of a newly declared object. Assignment requires a modifiable lvalue, and an array does not qualify; later changes must write individual elements or use a copy operation.
Should I use strcpy or snprintf?
Use strcpy only after proving the source plus terminator fits and the ranges do not overlap. snprintf accepts a capacity but can truncate, so check both negative returns and returns greater than or equal to the capacity.
Does strncpy always make a safe string?
No. If the source length reaches the limit, strncpy does not append a terminating null byte. It also pads short sources. Prefer a deliberately checked string-copy policy instead of assuming its name guarantees safety.
Can a structure containing an array be assigned?
Yes. Whole-structure assignment copies the members, including array members. Assigning directly to an array member remains invalid.