Thread: 32/64 bit issue

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    63

    32/64 bit issue

    I did a bit of research but my old brain just could not figure out the problem here.
    I thought it might be a va_list issue but my "c" is horrid at best.

    The "c" source was produced with the latest BCX translator.
    According to the bug fixes CreateArr_internal was updated in 2010 for 32/64.

    It compiles fine as both a 32 and 64 bit app on my Win7 64 using TDM-GCC.
    The 32bit app runs fine but the 64bit app crashes after a couple iterations of the for loop.

    The 64 bit version fails also with PellesC 8 RC2 and VS 2013.

    To muddy the waters a bit it will compile and run fine using the latest Tiny c 64 bit.

    Don't beat me up too bad if there is something obvious as it's legacy code not written by me

    The basic source was submitted by a BCX user who was testing the REDIM PRESERVE functionality.

    I was going to test on linux also but I don't have a 64bit linux installation at preset.

    James

    This is a the basic source:
    Code:
    dim dynamic buffer$[10]
    dim num_lines as integer
    dim arr_size as integer
    
    arr_size = 10
    num_lines = 0
    
    
    for num_lines = 1 to 100
        if num_lines >= arr_size then
            print "*** growing from: " & STR$(arr_size) & " to: " & STR$(arr_size + 10);
            arr_size += 10
            redim preserve buffer$[arr_size]
            print " *** grown"
        end if
    next

    This is the translation:


    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    
    
    #define cSizeOfDefaultString 2048
    
    
    // *************************************************
    //               Standard Prototypes
    // *************************************************
    char*   BCX_TmpStr(size_t, size_t    , int    );
    char*   str (double);
    void*   CreateArr (void*, int, int, int, ...);
    void*   CreateArr_internal(void*, int, int, int, va_list);
    void    DestroyArr (void**, int, int);
    
    
    static char    **buffer;
    static int     num_lines;
    static int     arr_size;
    #ifndef BCXTmpStrSize
    #define BCXTmpStrSize  2048
    #endif
    
    
    char *BCX_TmpStr (size_t Bites, size_t  iPad, int iAlloc)
    {
        static int   StrCnt;
        static char *StrFunc[BCXTmpStrSize];
        StrCnt = (StrCnt + 1) & (BCXTmpStrSize - 1);
        if(StrFunc[StrCnt]) {
            free (StrFunc[StrCnt]);
            StrFunc[StrCnt] = NULL;
        }
    #if defined BCX_MAX_VAR_SIZE
        if(Bites * sizeof(char) > BCX_MAX_VAR_SIZE)
        {
            printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n", (int)(Bites * sizeof(char)), BCX_MAX_VAR_SIZE);
            abort();
        }
    #endif
        if(iAlloc) StrFunc[StrCnt] = (char*)calloc(Bites + iPad + 1, sizeof(char));
        return StrFunc[StrCnt];
    }
    
    
    
    
    char *str (double d)
    {
        register char *strtmp = BCX_TmpStr(24, 1, 1);
        sprintf(strtmp, "%.15G", d);
        return strtmp;
    }
    
    
    void *CreateArr(void *a, int elem_size, int update, int num_dims, ... )
    {
        va_list ap;
        void   *RetPtr;
    
    
        va_start(ap, num_dims);
        RetPtr = CreateArr_internal(a, elem_size, update, num_dims, ap);
        va_end(ap);
        return (RetPtr);
    }
    
    
    void *CreateArr_internal(void *a, int elem_size, int update, int num_dims, va_list ap)
    {
        size_t s, s1, s2;
        void **vp;
        va_list marker;
    
    
    #ifdef va_copy
        va_copy(marker, ap);
    #else
        marker = ap;
    #endif
        s = va_arg(marker, size_t);
        s2 = s + 2;
        if(num_dims == 1)
        {
            if(update && a)
                a = realloc(a, s2 * elem_size);
            else
                a = calloc(s2, elem_size);
            return a;
        }
        else if(update && a)
        {
            s1 = 0;
            vp = (void**)a;
            while(*vp && s1 <= s)
            {
                vp++;
                s1++;
            }
            if(s1 > s)
            {
                vp--;
                DestroyArr(vp, num_dims, 0);
            }
            a = realloc(a, s2 * sizeof(int *));
            s1 = 0;
            vp = (void**)a;
            while(*vp && s1 <= s)
            {
                vp++;
                s1++;
            }
            while(s1 < s2)
            {
                *(((int *)vp)) = 0;
                vp++;
                s1++;
            }
        }
        else
            a = calloc(s2 * sizeof(int *), 1);
        vp = (void**)a;
        if(--num_dims > 0)
        {
            for(s1 = 0; s1 < s; s1++)
            {
                vp[s1] = CreateArr_internal(vp[s1], elem_size, update, num_dims, marker);
            }
        }
        return a;
    }
    
    
    
    
    void DestroyArr (void** a, int num_dims, int top_free)
    {
        int i = 0;
        static int s = 0;
        if(num_dims == 1)
        {
            free(a);
            return;
        }
        s++;
        num_dims--;
        while(a[i])
        {
            DestroyArr((void**)a[i], num_dims, top_free);
            if(num_dims > 1)
                free(a[i]);
            a[i++] = NULL;
        }
        s--;
        if(s == 0 && top_free)
            free(a);
    }
    
    
    int main()
    {
        buffer = (char**)CreateArr (buffer, sizeof(char), 0, 2, 10, 2048);
        arr_size = 10;
        num_lines = 0;
        for(num_lines = 1; num_lines <= 100; num_lines += 1)
        {
            if(num_lines >= arr_size )
            {
                printf("%s%s%s%s", "*** growing from: ", str( arr_size), " to: ", str( arr_size + 10));
                arr_size += 10;
                buffer = (char**)CreateArr (buffer, sizeof(char), 1, 2, arr_size, 2048);
                printf("%s\n", " *** grown");
            }
        }
    
    
    
    
        return 0;
    
    
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    36,745
    > buffer = (char**)CreateArr (buffer, sizeof(char), 0, 2, 10, 2048);
    Because va_arg parameters have no prototype to assist with determining what the true type should be, everything matching the ... just follows the default promotion rules.

    Which can basically be summarised for integral quantities as "everything is an int".

    What you need to do is be more explicit about what the real types are.
    buffer = (char**)CreateArr (buffer, sizeof(char), 0, 2, (size_t)10, (size_t)2048);

    So that when it gets around to
    s = va_arg(marker, size_t);

    It knows the right sized variable is going to be in the right place on the stack.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    63
    Salem,
    Sounds good, but unfortunately it still crashes.

    James

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    3,472
    I suggest looking at the size of int with the three compilers you mentioned.
    I suggest using stdint.h types instead of int type.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    Good advice above,

    There's also a good link here.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bandwidth issue / network issue with wireless device communication
    By vlrk in forum Networking/Device Communication
    Replies: 0
    Last Post: 07-05-2010, 11:52 PM
  2. new issue
    By hiddenprophecy in forum C Programming
    Replies: 3
    Last Post: 04-15-2009, 05:59 PM
  3. DNS issue
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 08-02-2008, 10:15 AM
  4. dll issue
    By axr0284 in forum C++ Programming
    Replies: 1
    Last Post: 03-23-2006, 08:37 AM
  5. dll issue
    By yahn in forum C++ Programming
    Replies: 1
    Last Post: 01-20-2006, 10:40 PM