Variable length argument list - 32 / 64 bit problem?

Discussion in 'C Programming' started by Joakim Hove, Mar 14, 2008.

  1. Joakim Hove

    Joakim Hove Guest

    Hello,

    I have written the following (stripped down) code:

    /********************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>


    char * path_fmt_alloc_path(const char * fmt , ...) {
    char * new_path;
    va_list ap;
    va_start(ap , fmt);
    {
    int path_length = vsnprintf(new_path , 0 , fmt , ap);
    new_path = malloc(path_length + 1);
    vsnprintf(new_path , path_length + 1 , fmt , ap);
    }
    va_end(ap);
    return new_path;
    }


    int test(const char * fmt , int id) {
    char * s = path_fmt_alloc_path(fmt , id);
    printf("%d -> %s \n",id ,s);
    free(s);
    }



    int main(int argc, char **argv) {
    const char * fmt = "%d";

    test(fmt , 1 );
    test(fmt , 2 );
    test(fmt , 3 );
    }


    /*********************************/

    When compiling with:
    bash% gcc -m32 va_test.c
    I get the result:

    1 -> 1
    2 -> 2
    3 -> 3

    i.e. what I expected. However it fails when compiling in 64 bit mode:

    bash% gcc va_test.c
    1 -> -
    2 -> 0
    3 -> 0

    This is done with gcc version 3.4.6...


    /***************************/

    I am in some invoking undefined behaviour, or is this a bug somewhere
    in my 64 bit toolchain?


    Best Regards

    Joakim Hove
    Joakim Hove, Mar 14, 2008
    #1
    1. Advertising

  2. On Mar 14, 9:45 am, Joakim Hove <> wrote:
    > Hello,
    >
    > I have written the following (stripped down) code:
    >
    > /********************************/
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <stdarg.h>
    >
    > char * path_fmt_alloc_path(const char * fmt , ...) {
    > char * new_path;
    > va_list ap;
    > va_start(ap , fmt);
    > {
    > int path_length = vsnprintf(new_path , 0 , fmt , ap);


    new_path is not initialized. You mean to be printing to NULL here to
    get the length, but... Maybe whether you get it set to 0/NULL depends
    on which compiler you get. I'd suggest (vsnprintf(NULL,...) to make
    your meaning clear. If new_path is not 0, you are writing to a wild
    pointer.

    -David
    David Resnick, Mar 14, 2008
    #2
    1. Advertising

  3. Joakim Hove

    Eric Sosman Guest

    Joakim Hove wrote:
    > Hello,
    >
    > I have written the following (stripped down) code:
    >
    > /********************************/
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <stdarg.h>
    >
    >
    > char * path_fmt_alloc_path(const char * fmt , ...) {
    > char * new_path;
    > va_list ap;
    > va_start(ap , fmt);
    > {
    > int path_length = vsnprintf(new_path , 0 , fmt , ap);


    va_end(ap);
    va_start(ap, fmt);

    > new_path = malloc(path_length + 1);


    if (new_path != NULL)

    > vsnprintf(new_path , path_length + 1 , fmt , ap);
    > }
    > va_end(ap);
    > return new_path;
    > }
    >
    >
    > int test(const char * fmt , int id) {
    > char * s = path_fmt_alloc_path(fmt , id);


    if (s != NULL)

    > printf("%d -> %s \n",id ,s);
    > free(s);
    > }
    >
    >
    >
    > int main(int argc, char **argv) {
    > const char * fmt = "%d";
    >
    > test(fmt , 1 );
    > test(fmt , 2 );
    > test(fmt , 3 );
    > }
    > [...]
    > I am in some invoking undefined behaviour, or is this a bug somewhere
    > in my 64 bit toolchain?


    Try "refreshing" the va_list and see it that helps.

    --
    Eric Sosman, Mar 14, 2008
    #3
  4. Joakim Hove

    Joakim Hove Guest

    Hello,

    thank you both for answering. I have tried to explicitly initialize
    the new_path variable to NULL; but that did unfortunately not help.

    >      Try "refreshing" the va_list and see it that helps.


    Ehhh - what do you mean be refreshing?

    Best Regards

    Joakim
    Joakim Hove, Mar 14, 2008
    #4
  5. Joakim Hove

    Eric Sosman Guest

    Joakim Hove wrote:
    > Hello,
    >
    > thank you both for answering. I have tried to explicitly initialize
    > the new_path variable to NULL; but that did unfortunately not help.
    >
    >> Try "refreshing" the va_list and see it that helps.

    >
    > Ehhh - what do you mean be refreshing?


    Go back and look at the lines I added to your code.

    --
    Eric Sosman, Mar 14, 2008
    #5
  6. Joakim Hove

    Joakim Hove Guest

    On 14 Mar, 17:55, Eric Sosman <> wrote:

    > > Ehhh - what do you mean be refreshing?

    >
    >      Go back and look at the lines I added to your code.


    Got it - thanks a lot :) Now it is working.

    Joakim
    Joakim Hove, Mar 14, 2008
    #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. ANDERS FLODERUS
    Replies:
    1
    Views:
    369
    Rob Williscroft
    Dec 20, 2003
  2. Replies:
    3
    Views:
    609
  3. Ben Kial
    Replies:
    1
    Views:
    635
    Eric Enright
    Nov 15, 2004
  4. S?ren Gammelmark
    Replies:
    1
    Views:
    1,871
    Eric Sosman
    Jan 7, 2005
  5. Keve Nagy
    Replies:
    4
    Views:
    2,077
    Keve Nagy
    Apr 4, 2009
Loading...

Share This Page