1

I am using a simple string matching and searching. Why does *arr is never equal to point though their values(why does I) are same? I am confused what is the cause of this?Is it related to strings or is there any other reason? Any help would be appreciated. I am sorry if the question is not clear.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int search(char ** arr, int size, char *point);

int main()
{
    char *array[5]={0};
    char original[50];
    char toSearch[50];
    char *point;     
    int size=5,  searchIndex,i;

    /* Copy a string into the original array */
    strcpy(original, "why this is not equal");

    /* Copy the first 10 characters of the original array into the newcopy    array*/
    point = memcpy(toSearch, original, 10);

    /*string to search*/     
    array[2]="why this i";

    searchIndex = search(array, size, point);

    if(searchIndex == -1)
    {
        printf("%s does not exists in array \n", point);
    } else
    printf("%s is found at %d position.", toSearch, searchIndex + 1);

    return 0;
}

int search(char ** arr, int size, char *point)
{
    int index = 0;
    // Pointer to last array element arr[size - 1]
    char ** arrEnd = (arr + size - 1);

    /* Why *arr!=point is never false,
       even when both are giving out same values (why this I)?
    */
    while(arr <= arrEnd && *arr!=point)
    {
        printf("%s == %s", *arr,point);
        arr++;
        index++;
    }

    if(arr <= arrEnd)
    {
        printf("%s after found \n",*arr);
        return index;
    }

    return -1;
}

Output:

(null) == why this i 
(null) == why this i   
why this i == why this i  
(null) == why this i   
(null) == why this i 
why this i does not exists in array

Thank You

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Are you asking why the address of the variable of type array-of-char is not identical to the address of the string literal you copy to it? – Yunnosch Jul 03 '18 at 04:41
  • I had to rescan five times to discover the definition of `search()`. Your formatting almost seems designed to hide that function... ;-) My mistake, but I will fix your indentation to make it eaiser for others. – Yunnosch Jul 03 '18 at 04:59
  • isn't `*arr != point` comparing "pointers" and not strings it points to ? shouldn't you use a string comparison instead ? e.g. `strcmp()` – xdrm Jul 03 '18 at 05:06
  • @Yunnosch An answer already exists : https://stackoverflow.com/a/8004250/7477557 but I am pretty new to StackOverflow and don't know how to mark this thread as already answered. I let you do it if you don't mind. Thanks. – xdrm Jul 03 '18 at 05:20
  • @xdrm-brackets Try the lgrey word "flag" beneath the question. It should say something like "duplicate of ..." and if you click there allow you to give a link to the question which asks the same and has an accepted or upvoted answer. Feel free to do that now. I am however not convinced that the link you provided can serve as original of this as a dupe. – Yunnosch Jul 03 '18 at 05:22
  • Possible duplicate of [How do I properly compare strings?](https://stackoverflow.com/questions/8004237/how-do-i-properly-compare-strings) – xdrm Jul 03 '18 at 05:24
  • The issue isn't so much comparing strings, as using memcpy to copy a partial string and thereby not getting a null terminator. `point = memcpy(toSearch, original, 10);` needs a `point[10] = '\0';` after it. – Lundin Jul 03 '18 at 06:50

2 Answers2

2

I assume that you are asking why the address of the variable of type array-of-char is not identical to the address of the string literal you copy to it.

This is a tricky question, because, excuse me for saying so, it is unclear what could make you expect the address of any variable be different after copying something to it.

Consider the example of not one but two different arrays of char being filled with the same string literal.

char toSearch1[50];
char toSearch2[50];
char *point1;
char *point2;

point1 = memcpy(toSearch1, original, 10);
point2 = memcpy(toSearch2, original, 10);
/* or, depending on what to you is more convincingly copying the same literal */
point2 = memcpy(toSearch2, toSearch1, 10);

Afterwards, the two arrays are still two different variables of type array-of-char and memcpy returns the address of the destination, i.e. of the two different arrays.
Please imagine how those two arrays could have identical address now.

If you follow up with

strcpy(original1, "is this in one or both arrays?");

Would you then expect the two arrays to have different addresses again?

If this does not answer your question, you have a fundamentally different understanding of pointers and addresses of variables than most programmers and I recommend to revise it by finding a tutorial on pointers and addresses.

(Note, for this explanation of what you are asking about I am skipping the discussion of checking lengths in relation to array sizes, using safer versions of string copying, memcpy not correctly null terminating copied strings. All of that is however important for making reliable code, as e.g. Lundin correctly reminds us.)

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • You fail to mention that `memcpy(toSearch1, original, 10);` cuts off a sub-string but adds no null terminator, which is one of the biggest bugs in the original code. – Lundin Jul 03 '18 at 06:52
  • @Lundin Good point, I used that in the side note in my answer, assuming your permission. Thanks. – Yunnosch Jul 03 '18 at 11:52
1

In C, string are just null terminated char arrays. As ordinary arrays, they decay to pointers when directly used in expression. So when you write str1 == str2 you are just comparing the pointers to their first element.

And two pointers are only equal if they point to the very same object (same address). That is the reason why standard library offers strcmp to compare null terminated strings, and memcmp to compare arbitrary buffers of known size.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252