简体   繁体   中英

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 ?

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.

主要区别在于,后者为50个字符分配内存(str是第一个元素的指针),而前者仅声明一个指针(除了指针变量本身的内存之外,没有分配内存)。

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM