Reputation: 2586
I am having trouble trying to work with strings in c. I have this code:
#include <stdio.h>
#include <string.h>
int main()
{
char *result[2];
strcpy(result[0], "String 1");
strcpy(result[1], "String 2");
printf("%s\n", result[0]);
printf("%s\n", result[1]);
}
It compiles without warnings but it does not run. It says Segmentation fault, core dumped when executed
How can I assign values to a string array in C?
P.D. In this example I tried to assign literal strings to make the simplest reproducible code, I know I could assign literal strings directly using {"String 1", "String 2"}
or something like that, but in reality I need to assign a variable to result[0]
and another variable to result[1]
Upvotes: 0
Views: 346
Reputation: 23832
char *result[2]
is an array of 2 pointers, they are uninitialized, if you want to assign string literals to them you can't use strcpy
, that function copies the string to the memory location pointed by those pointers, but because they are uninitilized they don't point to any memory location. The behavior of such construct is undefined.
If these are meant only to be printed, you can just use the assignment operator:
const char *result[2];
result[0] = "String 1";
result[1] = "String 2";
Or
const char *result[2] = {"String 1", "String 2"};
You'll notice that I used const
, that's because those strings are read only, you can't change them.
If you'd like to change them you need to initialize the pointers, either by allocating memory or by otherwise making them point to some valid memory location:
#include <stdlib.h>
char *result[2];
result[0] = malloc(/*length of the string + null byte*/);
result[1] = malloc(/*length of the string + null byte*/);
Or
char str1[/*length of the string + null byte*/];
char str2[/*length of the string + null byte*/];
char *result[2] = {str1, str2};
strcpy(result[0], "String 1");
strcpy(result[1], "String 2");
With this, because you copied the strings, you can now change them, they are no longer read only.
In fact there are no warnings by default, but enabling extra warnings in your compiler will warn you, for instance with gcc, using -Wall
flag will produce the following warning:
main.c:10:5: warning: 'result[0]' is used uninitialized in this function [-Wuninitialized] 10 | printf("%s\n", result[0]);
You should always use char arrays, i.e char result[2][10]
when given the oportunity, using memory allocation when you don't need it is needless overhead for your program. Check these threads for more info on that:
Upvotes: 2
Reputation: 123578
char *result[1];
C does not automatically allocate space to store a string's contents - you have to do that yourself. In this case you've only allocated enough space to store a pointer value (i.e., an address)1. Since it's declared without an initializer, that pointer value is indeterminate - it could be 0
, it could be 0xdeadbeef
, it could be any other value. In this case, that indeterminate pointer value just happens to point to memory that's writable, so the operation succeeds.
But...
Since it was not obtained by using the &
operator on an object during that object's lifetime or through a malloc
, calloc
, or realloc
call, that pointer value is invalid and the behavior on attempting to write through an invalid pointer is undefined. Unfortunately, one of the symptoms of undefined behavior is working as expected - as long as you don't clobber anything "important" your code will appear to function correctly.
char *result[2];
Same deal as above, although this time one or both of the indeterminate pointer values points to memory that is not writable, hence the runtime error.
Strings (including string literals) are ultimately stored in arrays of character type, so you'll have to allocate arrays that are long enough to store the entire string plus the terminator. "String 1"
is 8 characters long, so you need to allocate an array that's at least 9 characters wide to store the string plus the terminator:
char result[9];
strcpy( result, "String 1" );
or if your implementation supports variable-length arrays2, you can do:
size_t len = strlen( "String 1" );
char result[len + 1];
strcpy( result, "String 1" );
or if you want to allocate memory dynamically:
size_t len = strlen( "String 1" );
char *result = malloc( len + 1 );
if ( result )
strcpy( result, "String 1" );
If you want an array of strings, you'll have to use a 2D array of char:
char result[2][9];
strcpy( result[0], "String 1" );
strcpy( result[1], "String 2" );
or an array of pointers to char
that point to other arrays or dynamic memory:
char *result[2];
result[0] = malloc( strlen( "String 1" ) + 1 );
result[1] = malloc( strlen( "String 2" ) + 1 );
if ( result[0] )
strcpy( result[0], "String 1" );
if ( result[1] )
strcpy( result[1], "String 2" );
Upvotes: 1