2

a simple question:

this function worked perfectly on my 32 Bit Linux then I got a 64 Bit Linux and now it is no longer working. I've narrowed it down to this function in converting the data from Char to Int. it no longer does this. this is where I am stuck at right now. all this functions is doing is taking a format like this 100x100 then chopping out the x and keeping the two numbers on both sides then changing them into Int's.

Using atoi is now returning junk now that I am running it on this 64bit Linux. what function call do I have to use that will make it work again only on both 32 and 64 bit Linux programs now?

int findX(char *whereisX, int *rW, int *rH)
{
printf("entering findx dia is %s\n\n", whereisX);
char *tok1, *tok2, *saveptr;
char x = (int) malloc(sizeof(whereisX));

char str1[x];
int bW, bH;

strcpy(str1, whereisX);

tok1 = strtok_r(whereisX, "x", &saveptr);
tok2 = strtok_r(NULL, "x", &saveptr);

if ( tok2 == NULL)
{   printf("found return 1\n");
    return 1;
}
 else
    { printf("returning 0\n");
        tok1 = strtok_r(str1, "x", &saveptr);
        tok2 = strtok_r(NULL, "x", &saveptr);

        printf("tok1 is .. %s and tok2 is %s\n", tok1 , tok2);

    // here is where I am converting it from Char to Int
    // using atoi now gives me back junk 

     // bW = atoi(tok1);
     //    bH = atoi(tok2);


    bW = atoll(tok1);
    bH = atoll(tok2);
        printf("bW is %c and bH is %c\n", bW, bH);
       // printf("string -- bW is %s and bH is %s\n", bW,bH);
    /* assigning the results to the output */
       *rW = bW;
       *rH = bH;
    printf("rW is %s  rH is %s\n", rW  , rH); 
       return 0;
     }
} //end findX

output is

tok1 is .. 200 and tok2 is 100
// after converting from char to int using atoi
bW is � and bH is d
rW is �  rH is d
uxserx-bw
  • 241
  • 1
  • 2
  • 10
  • 3
    `char x = (int) malloc(sizeof(whereisX));` makes no sense. – Weather Vane Apr 15 '15 at 19:23
  • Check 3d line of your function... – Adriano Repetti Apr 15 '15 at 19:24
  • 1
    There are **at least** two errors: the nonsense `malloc` and the `printf("bW is %c and bH is %c\n", bW, bH);`: if bW and bH are int, then you should use %d – xanatos Apr 15 '15 at 19:46
  • I don't care about the printf because for two reasons I am not a seasoned programmer never will be -- I just tossed them in to get some out put to see what was happening with my code -- I just took this code added to it making the program give me more power to do to whatever I wanted to an image then then what the other person did. the printf are going away being removed. this is the only program I've ever written in C and most likely the last one too @xanatos – uxserx-bw Apr 15 '15 at 20:15

2 Answers2

5

These lines which you use to assign memory to copy the passed string are nonsense.

char x = (int) malloc(sizeof(whereisX));    // does not give the string length
char str1[x];                               // does not allow for terminator
int bW, bH;
strcpy(str1, whereisX);

Would be better as

char str1[1+strlen(whereisX)];
strcpy(str1, whereisX);

It's a wonder that your earlier version worked at all!

EDIT

Lets walk through it:

char x = (int) malloc(sizeof(whereisX));

The malloc allocates memory for a char* pointer - previously 4 bytes, now 8.

The (int)malloc converts the address of the memory allocated to an integer.

The char x = then stores the integer in 8 bits. This has nothing to do with the length of the string you will copy.

Next char str1[x]; assigns an array of a size totally unrelated to the length of string you will copy. Even if you did have the right length, it need to be one element longer to take the nul terminator. If it worked before, is pure luck that you ended up with a long enough array.

But switching to a different compiler has shown up this bug.

So rather than say I haven't answered your question, please correct your mistake and see if it fixes the problem. Maybe it will, maybe not: I haven't looked past line 3 to see if there are any other howlers.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • it was only giving me"" mhsetroot-v1.6.2.c: In function ‘findX’: mhsetroot-v1.6.2.c:728:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] "" that and it still worked BUT I MUST ADD: changing it to what you suggested fixed my problem --- THANKS!!!!!! @WeatherVane – uxserx-bw Apr 15 '15 at 19:42
  • @uxserx-bw don't fix warnings by throwing casts at them; instead try to understand what the warning is trying to warn you about – M.M Apr 15 '15 at 20:26
1

The correct version of your code is:

int findX(char *whereisX, int *rW, int *rH)
{
    printf("entering findx dia is %s\n\n", whereisX);
    char *tok1, *tok2, *saveptr;

    char *str1 = (char*)malloc(1 + strlen(whereisX));
    int bW, bH;

    strcpy(str1, whereisX);

    tok1 = strtok_k(whereisX, "x", &saveptr);
    tok2 = strtok_k(NULL, "x", &saveptr);

    if (tok2 == NULL)
    {
        printf("found return 1\n");
        free(str1);
        return 1;
    }
    else
    {
        printf("returning 0\n");
        tok1 = strtok_k(str1, "x", &saveptr);
        tok2 = strtok_k(NULL, "x", &saveptr);

        printf("tok1 is .. %s and tok2 is %s\n", tok1, tok2);

        bW = atoi(tok1);
        bH = atoi(tok2);

        printf("bW is %d and bH is %d\n", bW, bH);
        /* assigning the results to the output */
        *rW = bW;
        *rH = bH;

        printf("rW is %d  rH is %d\n", *rW, *rH);
        printf("tok1 is %s  tok2 is %s\n", tok1, tok2);

        free(str1);
        return 0;
    }
} //end findX

Note the differences: you were using malloc in the totally wrong way, you were using printf format identifiers in the totally wrong way, you weren't freeing the allocated string.

I'll add that you are doing the strtok_r twice (once outside the if and once inside the if). The two will return the same data, because str1 is a copy of whereisX

The code then can be simplified to:

int findX(char *whereisX, int *rW, int *rH)
{
    printf("entering findx dia is %s\n\n", whereisX);
    char *tok1, *tok2, *saveptr;

    int bW, bH;

    tok1 = strtok_k(whereisX, "x", &saveptr);
    tok2 = strtok_k(NULL, "x", &saveptr);

    if (tok2 == NULL)
    {
        printf("found return 1\n");
        return 1;
    }
    else
    {
        printf("returning 0\n");

        printf("tok1 is .. %s and tok2 is %s\n", tok1, tok2);

        bW = atoi(tok1);
        bH = atoi(tok2);
        printf("bW is %d and bH is %d\n", bW, bH);
        // printf("string -- bW is %s and bH is %s\n", bW,bH);
        /* assigning the results to the output */
        *rW = bW;
        *rH = bH;
        printf("rW is %d  rH is %d\n", *rW, *rH);
        printf("tok1 is %s  tok2 is %s\n", tok1, tok2);
        return 0;
    }
} //end findX

The fact that random programs written in C sometimes run returning somethings that seems to be correct doesn't mean they are correct. It only means that you got lucky. This luck doesn't ever last.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Great - wonderful last comment - programming by accident. +1 – jim mcnamara Apr 15 '15 at 20:00
  • @jimmcnamara go back and look at his lecture about programming by luck example "answer" did for my function -- he needs to take his own advice – uxserx-bw Apr 15 '15 at 20:18
  • You repeated OP's mistake of [casting malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). OP's code can serve as a counter-example to those who pooh-pooh the idea that one of the disadvantages of casting malloc is that it can hide a useful compiler diagnostic. – M.M Apr 15 '15 at 20:25
  • @xanatos your code just screws up the function more then it already was -- looks to me you're not heading your own advice -- mods took out all the errors it cost me trying it your way that I added to your post -- showing how wrong you where – uxserx-bw Apr 15 '15 at 20:26
  • @WeatherVane char str1[1+strlen(whereisX)]; strcpy(str1, whereisX); that fixed all my problems thanks --- – uxserx-bw Apr 15 '15 at 20:30