1

I expect to output:

acej

which works fine with this algorithm but there is a problem with outputting the result and this problem causes stack to overflow.

How do I fix it?

#include <iostream>
#include <vector>

std::vector<char> charAt(std::vector<char> str)
{
    std::vector<char> result;
    result.resize(str.size());

    for (int i = 0; i < str.size(); i++)
    {
        if (i % 2 == 0)
        {
            for (int j = 0; j < str.size(); j++)
            {
                if (result[j] == '\0')
                {
                    result[j] = str[i];
                    break;
                }
            }
        }
    }
    return result;
}

std::ostream& operator<<(std::ostream& stream, std::vector<char> vector)
{
    stream << "Vector: " << vector << std::endl;
    return stream;
}

int main() {
    std::vector<char> foo = { 'a', 'b','c','d','e','f','j' };
    std::vector<char> bar = charAt(foo);
    std::cout << bar << std::endl;
}
10
  • can you provide as well a minimal working example of how you're instanciating and calling this? Commented Jan 23, 2017 at 10:06
  • 3
    stream << "Vector: " << vector << std::endl; What did you expect this to do? Commented Jan 23, 2017 at 10:07
  • 1
    I don't think you have a stack overflow, but a plain bug. A vector of characters is not a string, so how come you expect it to contain '\0'? Commented Jan 23, 2017 at 10:07
  • @Lundin: It's an infinite recursion. Definitely stack overflow. Though you're right also, that's a bug. The loop iterates over j but then looks j up in the wrong container. Commented Jan 23, 2017 at 10:07
  • Oh, I didn't even read the code inside the overloaded operator :) Commented Jan 23, 2017 at 10:08

3 Answers 3

3

Lets take a closer look at your output operator:

std::ostream& operator<<(std::ostream& stream, std::vector<char> vector)
{
    stream << "Vector: " << vector << std::endl;
    return stream;
}

It's called when you output a std::vector<char>. It will then output a std::vector<char> which causes a recursive call, and so on in infinity (or until you get a stack overflow).

What your output operator needs to to is iterate over the vector and output each element.


On an unrelated note, don't pass the vector by value to the function. Instead use a constant reference:

std::ostream& operator<<(std::ostream& stream, std::vector<char> const& vector) { ... }
Sign up to request clarification or add additional context in comments.

Comments

1

Well, your operator<< is not only useless (since it does nothing but wrap the same line of code that you have in main anyway), but it's also calling itself recursively, so you get a SO eventually:

std::ostream& operator<<(std::ostream& stream, std::vector<char> vector)
{
    stream << "Vector: " << vector << std::endl;
                         \__________/
                                ^
                                |
                             recursion right here  
    return stream;
}

You probably want something like

std::ostream& operator<<(std::ostream& stream, std::vector<char> vector)
{
    stream << "Vector: " << std::endl;
    for(size_t i = 0; i < vector.size(); ++i)
        stream  << vector[i] << " ";
    stream  << std::endl;
    return stream;
}

Also your charAt could be improved:

std::vector<char> charAt(const std::vector<char> & str)
{
    std::vector<char> result;

    for (size_t i = 0; i < str.size(); i++)
    {
        if (i % 2 == 0)
        {
            result.push_back(str[i]);
        }
    }
    return result;
}

1 Comment

size_t i if you want to avoid 'signed/unsigned comparison' warnings. Personally I'd avoid the whole issue with for (auto c: vector) { stream << c << ' ' ; }
0

Did you intend to use std::string and used incorrect STL container instead.

#include <iostream>

std::string charAt(std::string str)
{
    std::string result;
    result.resize(str.size());

    for (int i = 0; i < str.size(); i++)
    {
        if (i % 2 == 0)
        {
            for (int j = 0; j < str.size(); j++)
            {
                if (result[j] == '\0')
                {
                    result[j] = str[i];
                    break;
                }
            }
        }
    }
    return result;
}

int main() {
    std::string foo = { 'a', 'b', 'c', 'd', 'e', 'f', 'j' };
    std::string bar = charAt(foo);
    std::cout << bar << std::endl;
}

Output

acej

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.