1

I am studying the C language.

When I pass a pointer to gets(), I find it can work well.

char *ptr;
gets(ptr);
puts(ptr);

But if I define an array of pointers, it doesn't work.

char *ptr[4];
int i=0;
for(i=0;i<4;++i)
    gets(ptr[i]);
for(i=0;i<4;++i)
    puts(ptr[i]);

Are they different, or is the first part wrong in fact? I want to know the reason.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    You need to allocate memory for the pointer to point to. – Barmar Mar 12 '20 at 08:41
  • 3
    Never *ever* call `gets`! It's a [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) function, which have even been removed from the C specification. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. – Some programmer dude Mar 12 '20 at 08:41
  • you also need to stop using `gets`: it's deprecated and a huge security risk – Jean-François Fabre Mar 12 '20 at 08:41
  • There is also the `gets_s` alternative function too which also performs bounds-checking. – Dai Mar 12 '20 at 08:42
  • 1
    As for your problem, if you have a pointer you need to make it actually *point* somewhere before attempting to use it. Attempting to dereference an invalid pointer leads to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Mar 12 '20 at 08:42

3 Answers3

1
char *ptr[4];
int i=0;
for(i=0;i<4;++i)
    gets(ptr[i]);

This is not valid C code as you did not allocate space for ptr[i]. On the other hand, never use gets because it's a function that does not check for buffer limit.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
1

The pointer has to point somewhere first.

#define BUFSIZE 100

char *ptr = malloc(BUFSIZE);
fgets(stdin, ptr, BUFSIZE);
puts(ptr);

char *ptr[4];
int i=0;
for(i=0;i<4;++i) {
    ptr[i] = malloc(BUFSIZE);
    fgets(ptr[i], BUFSIZE, stdin);
}
for(i=0;i<4;++i) {
    puts(ptr[i]);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • regarding: `fgets(stdin, ptr, BUFSIZE);` The syntax for `fgets()` is: `char *fgets(char *s, int size, FILE *stream);` so the posted code is nonsense – user3629249 Mar 14 '20 at 04:19
  • @user3629249 Sorry, I misremembered the argument order. – Barmar Mar 14 '20 at 04:25
1

You pass a pointer to a function (e.g. gets()) that writes data to a memory location pointed by your pointer. In your case, you have the uninitialized pointer, which means it points to a random memory location (where applications or an operating system resides). This leads to random effects - from "working" to abnormal termination or hanging. You need to reserve memory and assign pointer to point there, e.g. by:

char *ptr = (char*)malloc(256);

gets(ptr);
puts(ptr);

free(ptr);

Consider to use gets_s() that is more secure.

Dr. Andrey Belkin
  • 795
  • 1
  • 9
  • 28
  • 1
    Note that `gets_s()` is only available on Windows. Using `fgets()` is a reasonable alternative, but it does retain the newline whereas `gets_s()` removes it. – Jonathan Leffler Mar 12 '20 at 08:56