Lundu Harianja
Lundu Harianja

Reputation: 463

Pointer to char and character array in C

I'm always wondering what is the difference between those two in C

char *str;
char str[50];

I have the following code used to read string from user input instead of using gets.

int read_line(char *str, int n);

int main (int *argc, char *argv[])
{
  char *str;

  read_line(str, 50);
  printf("%s", str);
  return 0;
}

int read_line(char *str, int n)
{
  int ch, i = 0;

  while((ch = getchar()) != '\n')
  {
    if(i < n)
    {
        *str++ = ch;
        i++;
    }
}
*str = '\0';

return i;
}

The compilation works fine as expected but get crashed when I tried to run. And then I change the argument to the read_line() function, instead of char *str i use char str[50].

The program runs as expected when using char *str[50] as argument.

can someone explain why this happens? or what is the main difference of pointer to char and character array?

Upvotes: 0

Views: 821

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 310910

The difference will be seen at once if you will run this simple program

#include <stdio.h>

int main( void )
{
    char *str1;
    char str2[50];

    printf( "%zu\n", sizeof( str1 ) );
    printf( "%zu\n", sizeof( str2 ) );
}

The program output might look like

4
50

As you see the array str2 has enough memory to store a string up to 50 characters while the pointer can store only an address of some memory.

When you pass an array to a function as in your code

read_line(str2, 50);

(where str2 declared like char str2[50];) then the array name is implicitly converted to pointer to its first element. Thus for example these function declarations are equivalent

int read_line(char *str, int n);
int read_line(char str[50], int n);

or even like

int read_line(char str[100], int n);
int read_line(char str[], int n);

and declare the same one function because the parameter declared like array is adjusted to pointer.

So when you pass the array the function gets pointer to the first element of the array for which the memory is already allocated because the array was defined.

When you pass the pointer as you did in this main function

int main (int *argc, char *argv[])
{
  char *str;

  read_line(str, 50);
  printf("%s", str);
  return 0;
}

then it was not initialized and has some indertermined value. As result the program behaviour is undefined. The pointer shall point to some allocated memory where input data can be stored.

For example you can do this the following ways

int main (int *argc, char *argv[])
{
  char *str1;
  char str2[50];

  str1 = str2;

  read_line(str1, 50);
  printf("%s", str1);

  return 0;
}

or

int main (int *argc, char *argv[])
{
  char *str = malloc( 50 * sizeof( char ) );

  read_line(str, 50);
  printf("%s", str);

  free( str );

  return 0;
}

Upvotes: 1

SzG
SzG

Reputation: 12609

Array ids more or less work like pointers.

But with pointers you always need to do 3 steps manually:

  • create the pointer
  • allocate memory to point to
  • initialize the pointer to point there

char str[50]; does all three, while char *str; only creates an uninitialized pointer, and you don't even create a buffer to point to.

Further differences between pointers and array ids:

  • an array id represents the array's address in compile time only, while the pointer stores an address in memory, and you might even change it.
  • sizeof array returns the array size, while sizeof ptr returns the size of memory needed to store an address.

Upvotes: 2

Mandrill
Mandrill

Reputation: 256

The main difference is the later allocates memory for 50 char (str is a pointer for the first element) while the former just declares a pointer (no memory is allocated, besides the memory for the pointer variable itself).

Upvotes: 1

Related Questions