std::find does not work when using strdup

406 views Asked by At

I am using a std::vector to store some strings, later I try to std::find them but passing through strdup, as shown in the sample code, It does not work, std::find returns last, which means it did not find the string, but I can see that it is there, as I access it through the std::vector::at function, and it is displayed correctly. What is the problem?

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <stdint.h>
#include <string.h>

int main()
{
    std::vector<char*> signal_list;
    std::vector<char*>::iterator it;
    char *temp;
    char *temp2;

    signal_list.push_back("DDF_LTEsyn__CALLER");
    signal_list.push_back("DDF_LTEsyn__FFT_ctrl");
    signal_list.push_back("DDF_LTEsyn__IFFT_ctrl");
    signal_list.push_back("DDF_LTEsyn__ae_ctrl");
    signal_list.push_back("DDF_LTEsyn__cwp_ctrl");
    signal_list.push_back("DDF_LTEsyn__decision_ctrl");
    signal_list.push_back("DDF_LTEsyn__ovelap_ctrl");
    signal_list.push_back("DDF_LTEsyn__pilots_ctrl");
    signal_list.push_back("DDF_LTEsyn__pre_ctrl");
    signal_list.push_back("DDF_LTEsyn__rep_ctrl");

    temp2 = strdup(signal_list.at(3));

    printf("There is %s at position %d\n",temp2, 3);

    it = find(signal_list.begin(), signal_list.end(), temp2);

    printf("i found %s at position %d ",temp2, it - signal_list.begin());

}
2

There are 2 answers

1
AudioBubble On BEST ANSWER

You're comparing pointer addresses, not strings. You should use a std::vector<std::string> or use std::find_if() and pass it a predicate that can compare char pointers.

Here is how you could do the second of those:

bool compare(const char *str1, const char *str2)
{
    return strcmp(str1, str2) == 0;
}

it = std::find_if(signal_list.begin(), signal_list.end(), std::bind2nd(std::ptr_fun(compare), tmp2));
2
Martin York On

That's because the find is comparing pointers.

The default action is to compare the pointer value (not the string value).

Two options:
A: Change

temp2 = strdup(signal_list.at(3));

// Change this to:

temp2 = signal_list.at(3);

Now it will find a match on the two pointers.

B: switch to using std::string rather than char*

std::vector<char*>   signal_list;
char*                temp2;

// Change to:

std::vector<std::string>  signal_list;
std::string               temp2;

Now it will use string comparison and behave as you expect.

NOTE: String literals have a type of char const* not char*. Thus it is very dangerous to store them in a vector<char*> like that. Any attempt to modify them will likely crash your application. At least use vector<char const*>. If you were watching your warnings, the compiler will have warned you about a deprecated conversion from char const* to char*.