FAQ Clarification

This is a discussion on FAQ Clarification within the C Programming forums, part of the General Programming Boards category; Why gets() is bad / Buffer Overflows In this FAQ, you state that "gets() has only received the name of ...

  1. #1
    Ness
    Guest

    Question FAQ Clarification

    Why gets() is bad / Buffer Overflows

    In this FAQ, you state that "gets() has only received the name of the array (a pointer), it does not know how big the array is, and it is impossible to determine this from the pointer alone."

    However, it IS possible to determine the number of elements in any array by using the sizeof keyword, at least in tests that I have conducted in Microsoft Visual C++ and Borland C++ Builder.

    For example, the following code prints the number of elements of the array, line twice. Once using this method and the other using the constant value that was used to declare the array.

    Source:

    #include <stdio.h>
    #define MAXLINE 100

    int main(int argc, char *argv[])
    {
    char line[MAXLINE + 1]; /* Extra element for null character. */
    int printed;

    printed = printf("%u %u\n", MAXLINE, sizeof(line) / sizeof(*line));

    return (printed == 7 ? 0 : 1);
    }

    Output:

    101 101

  2. #2
    _Elixia_
    Guest
    I always thought that "sizeof" was a resolved by the compiler at the compile time. So it only works on structures and arrays with known values. It does not work with arrays such as "char *p" as it will not know how many char's "p" points to.

    Therefore "sizeof" can not be used. There are no other ways to determine the length of an array from the pointer alone.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Knowning the size does you no good. Your user can still type whatever they want, regardless of the actual size:
    Code:
    int main( void )
    {
        char foo[2];
    
        gets( foo );
    
        return 0;
    }
    Sure, you can find out for sure that the size is 2, but this doesn't prevent me from typing in 100 characters if I like.

    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Ness
    Guest

    Post

    Oops, the output should read:

    100 101

    because the MAXLINE constant is 100 and will always be 100. Silly me.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    148
    >>I always thought that "sizeof" was a resolved by the compiler at the compile time.
    With one exception,variable length arrays in C99.
    Code:
    int size;
    scanf("%d",&size);
    int array[size];
    sizeof(array); //Runtime,not Compiletime

  6. #6
    Ness
    Guest
    Knowning the size does you no good. Your user can still type whatever they want, regardless of the actual size
    I'm talking about the fact that it is possible to know the length of a character array that is declared at compile time like, char array[50] using sizeof(array) / sizeof(*array).

    I don't know what you're talking about! =)

  7. #7
    Ness
    Guest
    Sure, you can find out for sure that the size is 2, but this doesn't prevent me from typing in 100 characters if I like.
    I'm not saying it does. I'm just saying that gets can find out, but it doesn't care to.

  8. #8
    Ness
    Guest
    So it only works on structures and arrays with known values.
    So, it would'nt work if I malloc a character array dynamically, for example?

  9. #9
    Ness
    Guest
    [QUOTE]there is nothing you can do here which will
    // reliably tell you that p points to 100 bytes[QUOTE]

    If the array was declared to be a 100 bytes at compile time as in your example, and you CAN use sizeof(buff) / sizeof(*buff) to reliably tell you the length than why would the pointer *p in your function be any different than buff?

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >I'm just saying that gets can find out, but it doesn't care to.

    No, it can't.
    Code:
    #include <stdio.h>
    
    char *foo(char *buffer)
    {
       printf("wrong size: %lu\n", (long unsigned)sizeof(buffer)/sizeof(*buffer));
       return NULL;
    }
    
    int main(void)
    {
       char line[100];
       printf("right size: %lu\n", (long unsigned)sizeof(line)/sizeof(*line));
       foo(line);
       return 0;
    }
    
    /* my output
    right size: 100
    wrong size: 4
    */
    >So, it would'nt work if I malloc a character array dynamically, for example?

    No, not there either.

    [edit]
    >If the array was declared to be a 100 bytes at compile time as in your example, and you CAN use sizeof(buff) / sizeof(*buff) to reliably tell you the length than why would the pointer *p in your function be any different than buff?

    Because an array is not a pointer.
    [/edit]
    Last edited by Dave_Sinkula; 06-10-2003 at 05:21 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Ness
    Guest
    Why is the buffer pointer in your function any different than the line pointer in main? The line pointer just gets passed to your function, where it is stored in the buffer pointer, they should be equal so why does sizeof return different results?

  12. #12
    Ness
    Guest
    But I thought any time you use the name of an array it is interpreted as a pointer to that array.

  13. #13
    Registered User
    Join Date
    May 2003
    Posts
    148
    >>But I thought any time you use the name of an array it is interpreted as a pointer to that array.

    6.3.2.1 Lvalues, arrays, and function designators
    Except when it is the operand of the sizeof operator or the unary & operator, or is a
    string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
    converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
    the array object and is not an lvalue.

  14. #14
    Ness
    Guest
    Originally posted by Wledge
    >>But I thought any time you use the name of an array it is interpreted as a pointer to that array.

    6.3.2.1 Lvalues, arrays, and function designators
    Oh, I get it. Thanks for the reference to the ANSI C Standard. I guess I better go back to writing my getline function, which will properly get a line of input from the user and stop complaining about how crappy gets is. And while I'm at it maybe I'll reread the chapter on pointers in K & R's The C Programming Language.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wiki FAQ
    By dwks in forum A Brief History of Cprogramming.com
    Replies: 192
    Last Post: 04-29-2008, 02:17 PM
  2. FAQ Check/Lock
    By RoD in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 10-15-2002, 12:21 PM
  3. FAQ - it is not a true list of FAQ
    By alpha561 in forum C Programming
    Replies: 1
    Last Post: 05-25-2002, 07:40 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21