Reputation: 89
I am playing with some code in C and also I am trying to understand relationship between pointers and arrays. As you probably know, when I want to make array it could be done like this:
char * arr = "abc";
or
char arr[] = {'a','b', 'c'};
But when I want to do 2D array. It must be done like this
char arr[3][10];
Why declaration like this crashes when I try to load string to that.
char * names[3];
for ( int i = 0; i < 3; i++ ) {
printf("Enter name %d: ", i+1 );
scanf("%s", names[i]);
}
// print names
printf("\nEntered names are: \n");
for ( int i = 0; i < 3; i++ ) {
printf("%s\n", names[i] );
}
It should be 2D array right? Because array is basically pointer. Could you please explain that? Thanks.
Upvotes: 3
Views: 139
Reputation: 23802
char * names[3];
Is not a 2D array, it's an array of three pointers to char
, if you want to store char arrays
in it you must allocate memory to each individual pointer, something like:
for(size_t i = 0; i < 3; i++){
names[i] = malloc(/*length your array of chars*/);
}
You can then store char arrays
, using you example:
for(size_t i = 0; i < 3; i++){
printf("Enter name %ld: ", i + 1 );
scanf("%29s", names[i]); //for a malloc size of 30
}
Note that you must be careful with scanf
, if the inputed string is longer then the memory allocated to store it you will have stack smashing, i.e. for names[i]
with size of 30
, you should use %29s
specifier, instead of %s
. Though this approach is not whitout its issues, namely possible characters left in stdin
buffer, it's definitely safer.
Alternatively you can assign them string literals (in this case it's best to declare the array as const
, otherwise if you try to edit one or more characters it'll result in a segfault):
const char* names[3];
for(size_t i = 0; i < 3; i++){
names[i] = "My string literal";
}
You can also make them point to existing char arrays
:
char arr[3][10];
char* names[3];
for(size_t i = 0; i < 3; i++){
names[i] = arr[i];
}
Upvotes: 5
Reputation: 1885
pointer is a type of variable, which can only contain an address of another variable. It can't contain any data. You can't store data into a pointer.Pointers should point at memory location.
So to use a pointer in the right way ,it must always point at a valid memory location in stack or memory dynamically allocated in heap.
this char * names[3]
is an array of pointers ,so you need to reserve memory for it and then initialize it.You need to use some thing like this:
char *name[3];
for(int i=0;i<3;i++)
{
name[i]=malloc(strlen(string)+1);
}
also you should allocate memory for char *arr
too.
char *arr=malloc(strlen(data)+1)
then initialized it.
Upvotes: 1
Reputation:
char * names_1[3];
It's not a pointer. It's an array of pointers.
char names_2[3][10]={"one", "two", "three"};
char (*p_names_2)[10]=names_2;
Now it's a pointer to your 2D-Array. Just define a function and try to use it with your "pointers" as parameters.
void print_names(char names[][10], const int row){
for(int i=0; i<row; i++)
puts(names[i]);
}
Now call it with:
print_names(names_2, 3);
print_names(p_names_2, 3);
print_names(names_1, 3); //WRONG
And you'll see the difference.
Upvotes: 2
Reputation: 3676
char* names[3]
is not strictly a 2D array (they don't exist in C or C++); it's an array of arrays. So each element of names contains simply a char*
, which has not been initialised.
Note also that a c-style string is a null-terminated array of chars, so your original arr
is not a c-style string. To make it a c-style string you would need:
char arr[] = {'a','b','c',0};
making it an array of length 4, not 3.
Missing off the null-terminator will mean that most functions will run off the end of the allocated memory, because they won't know when the string stops.
Upvotes: 1