Strange problem on GCC - PLEASE HELP!!

Discussion in 'C Programming' started by cpptutor2000@yahoo.com, Feb 11, 2005.

  1. Guest

    I am compiling and running the following code snippet on a Linux box -
    I am really
    puzzled by the answers. Could someone please tell me what might be
    wrong?

    void test(){
    int m = 0;
    int n = 0;
    int i = 0;
    int j = 0;

    double start = 0.0;
    double end = 0.0;
    double gap = 0.0;


    struct timeval tp;

    aes_context ctx;

    unsigned char buf[16];

    unsigned char key[32];

    for(i = 0; i < 16; i++){ buf = 'a'; }

    for(j = 0; j < 32; j++){ key[j] = '9'; }

    printf("%d, %d\n", strlen(buf), strlen(key));

    /* Some more code omitted */
    }

    The print statements provide the answers 16, 48
    Could someone please provide some hint as to what might be the problem?
     
    , Feb 11, 2005
    #1
    1. Advertising

  2. Michael Mair Guest

    wrote:
    > I am compiling and running the following code snippet on a Linux box -
    > I am really
    > puzzled by the answers. Could someone please tell me what might be
    > wrong?
    >
    > void test(){
    > int m = 0;
    > int n = 0;
    > int i = 0;
    > int j = 0;
    >
    > double start = 0.0;
    > double end = 0.0;
    > double gap = 0.0;
    >
    >
    > struct timeval tp;
    >
    > aes_context ctx;
    >
    > unsigned char buf[16];
    >
    > unsigned char key[32];
    >
    > for(i = 0; i < 16; i++){ buf = 'a'; }
    >
    > for(j = 0; j < 32; j++){ key[j] = '9'; }
    >
    > printf("%d, %d\n", strlen(buf), strlen(key));


    1. strlen() returns values of the type size_t; size_t is an unsigned
    integer type and not necessarily the same as unsigned int.
    With C89, use
    printf("%lu\n", (unsigned long)strlen(somestring));
    with C99, you have a separate length modifier for size_t:
    printf("%zu\n", strlen(somestring));
    2. Valid C strings are _always_ terminated by a character with the
    value 0, often written as '\0' and referred to as string terminator.
    Your arrays of char do not contain C strings. In order to do so, one
    array element in the range 0 .. sizeof buf -1 (or sizeof key -1,
    respectively) needs to be zero.
    Otherwise, strlen() keeps probably reading through the memory until
    it encounters a byte of value 0. Why probably? Because the behaviour
    is undefined. It is also possible that the program dies with a
    segmentation fault or that your computer crashes.

    >
    > /* Some more code omitted */
    > }
    >
    > The print statements provide the answers 16, 48
    > Could someone please provide some hint as to what might be the problem?


    In your case, it is possible that the first byte after the storage
    reserved for buf is '\0', so you get sizeof buf. Moreover, it could
    be that key is stored right before buf, so you have sizeof key plus
    sizeof buf until '\0' is encountered. This is highly speculative.

    To get you started:

    #define SOMELEN (16)
    .....
    char mybuf[SOMELEN+1];
    for (i=0; i<SOMELEN; i++)
    mybuf = '.';
    mybuf[SOMELEN] = '\0';
    printf("String length is %scorrect\n", strlen(mybuf)==SOMELEN
    ? "":"not ");

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Feb 11, 2005
    #2
    1. Advertising

  3. Mysidia Guest


    > unsigned char buf[16];
    >
    > unsigned char key[32];


    Try

    unsigned char buf[16] = {};
    unsigned char key[32] = {};

    to initialize them to all \0s

    so the strings will actually end (a string for use with the
    standard libraries (calls such as strlen, printf, etc) ends at some \0)

    as long as you keep some \0

    and go from there

    -Mysid
     
    Mysidia, Feb 12, 2005
    #3
  4. Jack Klein Guest

    On 11 Feb 2005 14:58:53 -0800, wrote in
    comp.lang.c:

    > I am compiling and running the following code snippet on a Linux box -
    > I am really
    > puzzled by the answers. Could someone please tell me what might be
    > wrong?
    >
    > void test(){
    > int m = 0;
    > int n = 0;
    > int i = 0;
    > int j = 0;
    >
    > double start = 0.0;
    > double end = 0.0;
    > double gap = 0.0;
    >
    >
    > struct timeval tp;
    >
    > aes_context ctx;
    >
    > unsigned char buf[16];
    >
    > unsigned char key[32];
    >
    > for(i = 0; i < 16; i++){ buf = 'a'; }
    >
    > for(j = 0; j < 32; j++){ key[j] = '9'; }
    >
    > printf("%d, %d\n", strlen(buf), strlen(key));


    Obviously you don't have a prototype for strlen() in scope, usually
    done by including <string.h>, or you are operating your compiler in a
    broken (non conforming) mode. Because the argument to strlen() must
    be a pointer to char, and you are passing pointer to unsigned char.
    No automatic conversion is possible, so each call to strlen() would be
    a constraint violation.

    Actually calling strlen() with a pointer to unsigned char produces
    undefined behavior.

    Even if you change buf and key to arrays of char, instead of unsigned
    char, they are not strings, just arrays. Calling strlen() with a
    pointer to char that is not a pointer to a string also produces
    undefined behavior.

    > /* Some more code omitted */
    > }
    >
    > The print statements provide the answers 16, 48
    > Could someone please provide some hint as to what might be the problem?


    So...

    1. Turn up the warning level on your compiler.

    2. Invoke it in standard conforming mode.

    3. Include <string.h> before calling strlen().

    4. Do not pass pointers to unsigned char to strlen().

    5. Do not pass pointers to character arrays that are not strings to
    strlen().

    Then your problem will go away.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Feb 12, 2005
    #4
  5. Bansidhar Guest

    I would suggest to make some modifications in your code as bellow

    unsigned char buf[17]; //array bound 17 to include '\0' string
    termination character.


    unsigned char key[33]; //Same justification as above.


    for(i = 0; i < 16; i++){ buf = 'a'; }


    for(j = 0; j < 32; j++){ key[j] = '9'; }

    buf = '\0'; /*This is required as string terminates
    with '\0' as you know*/
    key[j] = '\0';

    BTW just modifiying the code to unsigned char buf[17] = {}; will not
    work because = {}; does not implicitely put '\0' at all positions of
    array.
     
    Bansidhar, Feb 12, 2005
    #5
  6. Mysidia wrote:

    > Try
    >
    > unsigned char buf[16] = {};


    unsigned char buf[16] = { 0 };

    > unsigned char key[32] = {};


    unsigned char key[32] = { 0 };

    > to initialize them to all \0s



    There is no such thing as an empty initializer.


    Christian
     
    Christian Kandeler, Feb 14, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KK
    Replies:
    2
    Views:
    735
    Big Brian
    Oct 14, 2003
  2. Replies:
    8
    Views:
    466
  3. Kevin P. Fleming

    C99 structure initialization in gcc-2.95.3 vs gcc-3.3.1

    Kevin P. Fleming, Nov 6, 2003, in forum: C Programming
    Replies:
    2
    Views:
    683
    Kevin P. Fleming
    Nov 6, 2003
  4. Replies:
    1
    Views:
    343
    Roedy Green
    Apr 23, 2008
  5. mastermagrath
    Replies:
    4
    Views:
    481
    robic0
    Dec 1, 2005
Loading...

Share This Page