3

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.

3
  • 2
    The crash for char *names[3]; really depends on how you use it. What are you doing with this array? What is the problem this array is supposed to solve? Commented Mar 21, 2020 at 11:36
  • Detail: "when I want to make array it could be done like this: char arr * = "abc";". --> Here arr is a pointer, not an array, String literal "abc" is an array. Commented Mar 21, 2020 at 12:02
  • 1
    "Because array is basically pointer" --> Not so. An array is like an apartment building with many units. A pointer is like the address of the unit. I can easily carry the address written on paper in my pocket. I can not carry the unit. Commented Mar 21, 2020 at 12:30

4 Answers 4

5
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];
}
Sign up to request clarification or add additional context in comments.

Comments

2
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.

Comments

1

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.