-3

So I am trying to understand std:: search. First I created one array of a class and then copied to a vector.

Now I am trying to check if the contents of my vector appear in my array (i have modified one vector value, so they wouldn't be identical).

It is like the vector is empty, i cant cout the _brandName either!

This was my best try:

#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <iterator>

class Car{
    public:
    Car(){};
    Car(std::string brand, double speed){_brandName = brand; _speed = speed};
    ~Car(){};

    bool operator==(const Car& rhs){return _brandName == _brandName;}
    std::string GetBrand(){return _brandName;}

    private:
    std::string _brandName;
    double _speed;

};

int main(){


    Car carArray[4];

    carArray[0] = Car("BMW", 280);
    carArray[1] = Car("FORD", 300);
    carArray[2] = Car("FORD", 380);
    carArray[3] = Car("AUDI", 380);

    auto arraySize = sizeof(carArray) / sizeof(carArray[0]);
    std::vector<Car> carVector(carArray, carArray + arraySize);
    carVector[0] = Car("Ferrari", 400);
    std::cout << carVector[0].GetBrand();

    std::vector<Car>::iterator it;
    it = std::search(carVector.begin(), carVector.end(), std::begin(carArray), std::end(carArray));
    std::cout << it->GetBrand();
    return 0;
}

I had to add -1 to vector end otherwise I get the error: terminate called after throwing an instance of 'std::logic_error'

what(): basic_string::_M_construct null not valid

I think that the error is because I am trying to call the std::string constructor with the value NULL but I don't understand why it is saying that.

I don't know if my implementation of the std::search is right either, what is the right way?

daedsidog
  • 1,732
  • 2
  • 17
  • 36
Ninhow
  • 47
  • 7
  • 3
    Why does your class take a double for the second parameter of the constructor but has a `std::string` member? `_value(value)` is going to lead to badnees. – NathanOliver Dec 13 '18 at 19:47
  • 1
    you need to create a [MCVE]. You have stripped down your problem, so it is minimal, but you need to create a small snippet of code that compiles. We would then just copy paste your code in our compiler and see for ourselves. – bolov Dec 13 '18 at 19:48
  • Wrote it wrong, it was supposed to be a double. – Ninhow Dec 13 '18 at 19:58
  • set aside what NathanOliver said, which is indeed a cause of compile time errors (although the compiler should have directed you to that line when giving the error); why are you populating an array and then creating a vector out of that array, rather than starting directly with a vector? – Barnack Dec 13 '18 at 19:59
  • With the recent edit, the question is even less complete. Make an example that we can actually compile. – Ted Lyngmo Dec 13 '18 at 20:02
  • I am experimenting with the search algorithm, like I said before I just wrote the code trying to make a general picture of my problem. – Ninhow Dec 13 '18 at 20:03
  • Like @bolov said, post a minimal, complete and verifiable example. We can't help if you have us guessing. Pretend that you yourself are copying the code you've posted. Do you expect it to compile? – Ted Lyngmo Dec 13 '18 at 20:05
  • That will reproduce the same problem. – Ninhow Dec 13 '18 at 20:08
  • Try it. It lacks includes and classes (like `Car`) etc. ... and a `main` function. Edit: Now the `Car` class appeared but it's nowhere near complete. It will not compile. – Ted Lyngmo Dec 13 '18 at 20:09
  • I am sorry i was frustrated, i fixed everything. – Ninhow Dec 13 '18 at 20:16
  • Well ... no :-) It misses the implementations of the `Car()`, `~Car()` and `Car(std::string brand, double speed);` methods. – Ted Lyngmo Dec 13 '18 at 20:19
  • if u cant compile with that now than your ide is broken – Ninhow Dec 13 '18 at 20:24
  • @Ninhow 1) "_if u cant compile with that now than your ide is broken_" `Car(std::string brand, double speed){_brandName = brand; _speed = speed};` There is no `;` after `_speed = speed` statement. You should look into your own IDE.. 2) Consider enabling your warnings: `In member function 'bool Car::operator==(const Car&)': warning: unused parameter 'rhs' [-Wunused-parameter]` – Algirdas Preidžius Dec 13 '18 at 20:28
  • :-) ... and my _ide_ is `scan-build -v --force-analyze-debug-code g++ -fsanitize=undefined -std=c++17 -g -O3 -Wall -Wextra -Wshadow -Weffc++ -pedantic -pedantic-errors -Wc++14-compat -Wc++17-compat ...` – Ted Lyngmo Dec 13 '18 at 20:32
  • 1
    Your code doesnt match to description of your problem. Where two elements are modified? Your current code works fine because two ranges are identical. – rafix07 Dec 13 '18 at 20:40
  • I guess i have fixed all the issues with my question, i also understood that the printing of a vector argument isnt working it out, first "cout" isnt printing anything. – Ninhow Dec 13 '18 at 20:56

1 Answers1

2

You use this version of search algo:

template< class ForwardIt1, class ForwardIt2 >
ForwardIt1 search( ForwardIt1 first, ForwardIt1 last,
                   ForwardIt2 s_first, ForwardIt2 s_last );

search returns iterator to the beginning of first occurence of [s_first,s_last) in the range [first,last). If the occurence cannot be found last is returned. What you need to do is to check it value. Version without -1 crashes because search returns carVector.end() (you are passing into search two ranges, both have the same length and in one range you modified two items, so search cannot find occurence of the second range in the first one), and when you call getBrand() you are accessing the element of vector which doesn't exist, it leads to undefined behaviour.

std::vector<Car>::iterator it;
it = std::search(carVector.begin(), carVector.end(), std::begin(carArray), std::end(carArray));
if (it != carVector.end())
{
    // carArray was found in carVector, do sth here with it
    std::cout << it->GetBrand();
}
rafix07
  • 20,001
  • 3
  • 20
  • 33