4

I have following function to compare two char arrays in C:

short test(char buffer[], char word[], int length) {
    int i;
    for(i = 0; i < length; i++) {
        if(buffer[i] != word[i]) {
            return 0;
        }
    }
    return 1;
}

And somewhere in main:

char buffer[5]; //which is filled correctly later
...
test(buffer, "WORD", 5);

It returns 0 immediately at i = 0. If I change function to this:

short test(char buffer[], int length) {
    int i;
    char word[5] = "WORD";
    for(i = 0; i < length; i++) {
        if(buffer[i] != word[i]) {
            return 0;
        }
    }
    return 1;
}

... it works like a charm. In the first version of function test debugger says that buffer and word arrays are type of char*. In the second version of function test it says that the buffer is type of char* and the test array is type of char[]. Function strcmp() does not work neither.

What is actually wrong here? Program is made for PIC microcontroller, compiler is C18 and IDE is MPLAB.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
CAPS LOCK
  • 1,960
  • 3
  • 26
  • 41
  • you pass in word[] and then use ukaz[] ??? – Mitch Wheat Nov 24 '13 at 00:04
  • sorry where is ukaz coming from? – Jekyll Nov 24 '13 at 00:04
  • Woops ... forgot to translate that! Corrected now. @MitchWheat – CAPS LOCK Nov 24 '13 at 00:05
  • @drive235 You say `buffer` is filled in correctly but I'm skeptical. Also, in the second example you declare `word` as an array of 5 chars and then initialize it with 6 chars. I don't know what your compiler does with that but it's not how you should do it. You don't need to add `\0` to a literal string in C unless that string requires double null termination. – Carey Gregory Nov 24 '13 at 00:10
  • can you remove that '\0'? – Jekyll Nov 24 '13 at 00:10
  • 2
    I assume you know it returns 0 right away, because you put a printf() there or something to see that. Why not take a look at what buffer[0] and word[0] are? Might be the clue you're looking for. – Travis Griggs Nov 24 '13 at 00:11
  • @CareyGregory: buffer is filed with getsUSBUSART() function. – CAPS LOCK Nov 24 '13 at 00:15
  • @Jekyll: It's still the same. – CAPS LOCK Nov 24 '13 at 00:17
  • @drive235 sorry but the only C error I see is that there are 6 chars allocated. No majors error there. Are you sure that return value is 0? if it is 1 the length may be corrupted somehow – Jekyll Nov 24 '13 at 00:22
  • @Jekyll I have changed size to 4 chars. And yes I am sure. Tested with inserting breakpoints and variable watch. I have no idea why it's not working. – CAPS LOCK Nov 24 '13 at 00:24
  • @drive235 size need to be 5 but you don't want to put \0 which is automatically appended. Now you allocate 5 on 4 byte. it is still a mistake, please write =>char word[5] = "WORD"; – Jekyll Nov 24 '13 at 00:26
  • @Jekyll ok then 5. But still I don't see how this is connected to returning 0 at checking first char. If buffer is filled with WORD and word is filled with WORD, 'W' == 'W' ... but it says no. – CAPS LOCK Nov 24 '13 at 00:32
  • I was thinking about the fact that an overflow in the buffer may affect the index variable or the length – Jekyll Nov 24 '13 at 00:33

1 Answers1

4

Hmm...

Sometimes in embedded systems there is difference where strings are stored.

In the first example you define a string which is stored in flash code region only. So the comparison will fail with index 0 because of the memory area difference.

The second example you define a local variable which contain the same string. This will be located in RAM, so the comparison works since they are both in RAM.

I would test following:

char buffer[5]; //which is filled correctly later
char word[5] = "WORD";
...
test(buffer, word, 5);

Most likely it is going to work because the comparison is done in RAM totally.

Yes and remove the \0 since the "WORD" will null terminate automatically.

Remix
  • 56
  • 1
  • Man, you saved the day (night). Thank you! – CAPS LOCK Nov 24 '13 at 00:34
  • Good. It goes down to fact that PIC assembly is not able to do comparison between flash and ram. And those small device compilers are not good enough to handle the situation. Same thing happens sometimes with Keil and SDCC – Remix Nov 24 '13 at 08:01
  • 1
    As has been noted this is related to the PIC18 having a Harvard architecture with separate address spaces and instructions for accessing data in FLASH and variables in RAM. The standard libraries does supply a set of alternate string functions for dealing with FLASH pointers, in this case you want to try strncmppgm2ram(buffer, "WORD", length). Sidenote: MCC18 is a stupefyingly horrendous compiler, far beyond anything else I have ever encountered anywhere. If you value your sanity _please_ switch to XC18 instead. – doynax Dec 17 '13 at 15:34