Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 First element of array (rest are fine) is a non-value half the time after shuffle
Index -> Programming, C -> C Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
np_123




PostPosted: Tue May 09, 2017 1:18 am   Post subject: First element of array (rest are fine) is a non-value half the time after shuffle

The problem I am having is that I'm getting weird output when I try to shuffle an array of 'strings'.
When the array contains {"hi", "hola", "amigo"} half the time I get the same back, the other half this {"8y@", "hola", "amigo"} where @ is a weird character looking like a skinny rectangle.

The method giving problems is the shufflestring method below. I've omitted for clarity two interface methods that don't modify anything:

C:

char **arr;
shufflestring(arr, sz); /*sz is just length of the array*/

/* Modern Fisher-Yates shuffle */
void shufflestring(char *a[], int n) {
        srand((unsigned)time(NULL));
        for (int i = n - 1; i > 0; i--) {
                int j = rand() % (i + 1);
                char *temp;
                temp = a[i];
                a[i] = &a[j];
                a[j] = &temp;
        }
}



the exact same code works if instead of char** (array of 'strings' is what it's supposed to be) it's double a[] in the shuffle method and double* a being passed to it.
for example these work fine:

C:

/*Example1*/

char *str[5] = { "help", "hola", "hi", "amigo", "hitme"};
shufflestring(str, 5);
/* Modern Fisher-Yates shuffle */
void shufflestring(char *a[], int n) {
        srand((unsigned)time(NULL));
        for (int i = n - 1; i > 0; i--) {
                int j = rand() % (i + 1);
                char *temp = a[i];
                a[i] = a[j];
                a[j] = temp;
        }
}

/*Example2*/
double *arr;
shufflereal(arr, sz);

/* Modern Fisher-Yates shuffle */
void shufflereal(double a[], int n) {
        srand((unsigned)time(NULL));
        for (int i = n - 1; i > 0; i--) {
                int j = rand() % (i + 1);
                double temp = a[i];
                a[i] = a[j];
                a[j] = temp;
        }
}
Sponsor
Sponsor
Sponsor
sponsor
Insectoid




PostPosted: Tue May 09, 2017 3:20 pm   Post subject: RE:First element of array (rest are fine) is a non-value half the time after shuffle

I notice your char** example uses & in the swap, while your char*[] example does not. It's a long time since I've worked with C, but when you get random-looking strings, it's due to a pointer error. a[j] is already a pointer and doesn't need to be dereferenced. The reason your int example works is you are swapping the data directly, whereas your first looks like you're trying to swap pointers.
np_123




PostPosted: Tue May 09, 2017 4:57 pm   Post subject: Re: First element of array (rest are fine) is a non-value half the time after shuffle

yes, thanks, I've gotten rid of the & now, but the same problem still occurs with one exception: instead of a garbage string the first element ends up empty. And I do agree it's a pointer error of sorts.

I can't figure out how to test the values in an dynamic array (im compiling, debugging using VS) but I'm starting to think that maybe the 'array of strings' that I wish to pass to the method isn't being created/stored properly. Reasoning: when I attempt to DebugOutputString(arr[0]) it crashes, but DebugOutputString(arr) works

The following methods are the relevant top-level method calls that initiate everything
Note: OOTaddr is an alias for char *, OOTint -> long, ADDR_SIZE == 1; (unfortunately the MyExecutorScan isn't code I wrote so while I 'mostly' understand what's happening, I can't really explain it)

C:

void MIO_sort_sortstring(OOTaddr *sp)
{
        char **arr;
        OOTint sz;
        MyExecutorScan(sp, "AI", &arr, &sz);

        MIOSort_sortstring(arr, sz);
}


static void     MyExecutorScan (OOTaddr *sp, const char *param, ...)
{
   const char *pf = param;

   va_list curr_arg;

   va_start(curr_arg, param);

   while (*pf)
   {
        switch(*pf)
        {
            case 'r':
                // Skip the function result stack position
                sp += ADDR_SIZE;
                break;

            case 'A':
                {
                    OOTaddr *arg_arrayp = va_arg(curr_arg, OOTaddr *);

                    *arg_arrayp =  (OOTaddr) *sp;
                    sp += ADDR_SIZE*2;
                }
                break;

            case 'I':
                {
                    OOTint *arg_intp = va_arg(curr_arg, OOTint *);

                    *arg_intp = *((OOTint *) sp);
                    sp += INT_SIZE;
                }
                break;
        } // switch
        pf++;
    } // while
    va_end(curr_arg);
} // MyExecutorScan




int_vs_string_code.c
 Description:
includes methods and code enough for a partial trace and comparison between the working int array sorting and broken 'string' array

Download
 Filename:  int_vs_string_code.c
 Filesize:  2.26 KB
 Downloaded:  203 Time(s)

np_123




PostPosted: Tue May 09, 2017 9:23 pm   Post subject: Re: First element of array (rest are fine) is a non-value half the time after shuffle

I'm afraid it might have been a wild goose chase. The 'bug' seems to be not in my code, but in the program I'm extending (it's the OpenTuring project source, I doubt anyone's looked at that in years).

So what I gather the program is supposed to do is place/leave arguments on a stack frame which I later grab via pointer to the stack.

However, it appears to leave just the first element of the array on the stack at the and the rest I can't find.
How I came to that conclusion: DebugOutputString(*sp) prints hi ; and *(sp+2) is 3. (given the input i mentioned in the first post) Offsetting the pointer via *(sp + x) with values from -2 to 5 I can't find any other meaningful data

I don't honestly know if there's anything I can do to fix it without going into a bunch of obscure code. Unless there's some pointer offsetting magic I'm missing
np_123




PostPosted: Wed May 10, 2017 12:22 am   Post subject: Re: First element of array (rest are fine) is a non-value half the time after shuffle

and solved it - each further element of the array had an offset of 256.
as in, if 'hi' is at address x, hola is at x+256... meaning: *(sp) == "hi" and *(sp) + 256 == "hola"

I'm thinking the number 256 should be more than convenience, but doesn't ring any bells at the moment.

If anyone can confirm whether an offset of 256 (maybe it's a default string length/memory allocation?) can be assumed that'd be amazing
Display posts from previous:   
   Index -> Programming, C -> C Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 5 Posts ]
Jump to:   


Style:  
Search: