1
#include <stdio.h>

int main () 
{
    char str[40];
    printf("Enter a string : \n");
    gets(str);
    printf("You entered: %s\n", str);

    return 0;
};

in above code, if replace str to a pointer, char *str. Then NULL is out. Suppose gets defined by char *gets(char *str), it should use a pointer instead of array. All examples I saw are array not pointers. Thanks.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
John
  • 11
  • 1
  • 1
    I added the [tag:c] tag for you :) – wjandrea Mar 28 '21 at 17:09
  • 1
    [`gets` has been deprecated and removed from C for a long time](https://stackoverflow.com/q/1694036/995714) – phuclv Mar 28 '21 at 17:10
  • `char *str` allocates a variable for pointer to char, but pointer value can be anything, you need to have a valid pointer for the buffer. For example, if you want to allocate the buffer dynamically, you can use `malloc(3)`/`calloc(3)`. – Ammar Faizi Mar 28 '21 at 17:12
  • 1
    The parameter to `gets` is a pointer to the buffer for text, your code 40 character buffer. Changed to `char *`, it's pointer to undefined (probably causing crash), unless you set it as suggested by @AmmarFaizi. The return pointer from `gets` is not a new allocation for input text, it will be the same as you provide unless end-of-file or error, when it will be NULL. – Perette Mar 28 '21 at 17:21
  • @Perette arrays decay to pointers when passing to functions so there's nothing wrong with `gets(str)`. The only issue there is the use of `gets()` – phuclv Mar 30 '21 at 14:41
  • @phuclv Yes, however,I read the OP as asking why they can't just replace the `char[40]` with a `char *`, as if s/he is coming from a language where strings are first-rate citizens that manage themselves, so allocating buffer space for the strings is a new concept. But I agree, `gets` is bad, use `fgets` or another alternative, although that's unrelated to my reading of the question. – Perette Mar 31 '21 at 21:45

2 Answers2

2

function gets() is depracted your libc/compiler might ignore it. try use fgets() instead.

#include <stdio.h>

int main () 
{
    char str[40];
    printf("Enter a string : \n");
    if (fgets(str, sizeof(str), stdin) != NULL)
    {
        printf("You entered: %s\n", str);
    }

    return 0;
};

also if you want to don't use stack you need to give pointer that points allocated space. in code str also can be char *str = malloc(40); then change sizeof(str) to 40 since str is no longer stack.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
fsdfhdsjkhfjkds
  • 308
  • 1
  • 9
1

Really interesting question, I have been asked this question a lot!

you should have a bit background of pointers and memory to understand what is happening.

first let's have a brief review about pointers and memory:

  • our computer have some memory and we can use it in programming, anything that we store (in runtime) for example an int, array of doubles, some complex struct and strings(that they are array of characters) should be somewhere in memory.
  • pointers contain address of somewhere in memory, some of them know about that memory (how to read/write value) some of them don't.
  • there is a special value for pointers (NULL) that means nowhere, if pointer is pointing to NULL, that pointer is pointing not nowhere (obviously nowhere is not a valid address in memory)
  • array is specific type of pointer, a const pointer that is pointing to already allocated memory in stack.

and about gets function: let's think we want to re-implement such function (namely my_gets) , how we suppose to do that? how to return a string (array of characters)? these are options (as far as i know):

  • creating a local array in our function and fill it. then we should return it? no we cant! because that array is in stack of our function and after ending the function, our function data including this array will be popped automatically (handled by compiler). although nobody forbid us from returning that array, but that would cause dangling pointer problem.
  • allocating some space rather than stack (heap) and fill that. this is perfectly fine and there is methods and do this! for example readline (not in ansi c, you can find it here) will do this. the drawback of this method is that you should take care of that memory and free it later, it also may be not to optimum way and you may should copy that string to your already allocated memory
  • the last way (and way that gets use) is getting a pointer that is already pointing to a valid memory and fill that memory. you already know that gets want a pointer as input, I add that, that pointer should point to a valid and accessible memory that gets can fill it. if pointer is pointing to NULL (or maybe uninitialized and pointing to some where random) gets will fail writing and cause undefined behavior (segmentation fault for example)

some final points:

  • array solution work because array name is pointer that pointing to valid memory (array in stack) so it's OK and easy to understand.
  • If we don't want to use array, we can point our pointer to a valid memory, we need to use malloc/calloc to allocate a block of memory. see this:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int size = 40 * sizeof(char);
    char* p = malloc(size);
    printf("Enter a string : \n");
    if (fgets(p, size, stdin) != NULL) {
        printf("You entered: %s\n", p);
    }

    free(p);
    return 0;
}

  • gets is not secure because it doesn't care how much memory we have, it writes until and string ends and it may cause buffer overflow, better option (as people said) is fgets because it care memory size and will not exceed that. but my answer doesn't care it's fgets or gets.