skprime
skprime

Reputation: 55

C++ string::find crashes application

So I want to check if my const std::string &foo = "hello world"; contains another string const std::string &bar = "world";.

So I tried to use if statement like this: if (foo.find(bar) != std::string::npos). There is no errors but when I start my application it crashes. When I remove that code application works fine again.

Can somebody tell me how to use this function?

I tried to found reason, another tutorial but my code seems to be fine. And yeah I'm sure that I made a mistake somewhere.

EDIT:

Code:

#include "modelLoader.h"

#include <iostream>
#include <fstream>
#include <algorithm>
#include <strstream>
#include <string>

ModelAsset *ModelLoader::loadOBJModel(FilePath *objFile)
{
ModelAsset *model = new ModelAsset();

std::ifstream file(objFile->getPath());

std::vector<std::string*> lines;

std::string tempLine;

while(std::getline(file, tempLine))
{
    lines.push_back(&tempLine);
}

for(U32 i = 0; i < lines.size(); i++)
{
    if((*lines[i])[0] == '#') continue;
    else if((*lines[i])[0] == 'v' && (*lines[i])[1] == ' ')
    {
        F32 tempX, tempY, tempZ;
        sscanf(lines[i]->c_str(), "v %f %f %f %f", tempX, tempY, tempZ);

        model->verticles.push_back(new Vector3(tempX, tempY, tempZ));
    }
    else if((*lines[i])[0] == 'v' && (*lines[i])[1] == 'n')
    {
        F32 tempX, tempY, tempZ;
        sscanf(lines[i]->c_str(), "vn %f %f %f %f", tempX, tempY, tempZ);

        model->normalVectors.push_back(new Vector3(tempX, tempY, tempZ));
    }
    else if((*lines[i])[0] == 'v' && (*lines[i])[1] == 't')
    {
        F32 tempX, tempY, tempZ;
        sscanf(lines[i]->c_str(), "vt %f %f %f %f", tempX, tempY, tempZ);

        model->textureVectors.push_back(new Vector3(tempX, tempY, tempZ));
    }
    else if((*lines[i])[0] == 'f')
    {
        U16 counter = std::count(lines[i]->begin(), lines[i]->end(), '/');

        if(counter == 0)
        {
            S32 v1, v2, v3;
            sscanf(lines[i]->c_str(), "f %d %d %d", v1, v2, v3);

            model->faces.push_back(new Face(v1, v2, v3));
        }
        else if(counter == 3)
        {
            S32 v1, v2, v3;
            S32 vt1, vt2, vt3;
            sscanf(lines[i]->c_str(), "f %d/%d %d/%d %d/%d", v1, vt1, v2, vt2, v3, vt3);

            model->faces.push_back(new Face(v1, v2, v3, vt1, vt2, vt3));
        }
        else if(counter == 6)
        {

            /* Just testing if find works fine */
            const std::string &main = "hello world";
            const std::string &part = "world";

            if(main.find(part) != std::string::npos)
            {
                S32 v1, v2, v3;
                S32 vn;
                sscanf(lines[i]->c_str(), "f %d//%d %d//%d %d//%d", v1, vn, v2, vn, v3, vn);

                model->faces.push_back(new Face(v1, v2, v3, vn));
            }
            else
            {
                S32 v1, v2, v3;
                S32 vn;
                S32 vt1, vt2, vt3;
                sscanf(lines[i]->c_str(), "f %d/%d/%d %d/%d/%d %d/%d/%d", v1, vt1, vn, v2, vt2, vn, v3, vt3, vn);

                model->faces.push_back(new Face(v1, v2, v3, vt1, vt2, vt3, vn));
            }
        }
    }
}

    return model;
}

When I remove all with if(main.find...) my program works.

Upvotes: 0

Views: 688

Answers (1)

Damyan
Damyan

Reputation: 1613

The problem is with the sscanf lines:

S32 v1, v2, v3;
S32 vn;
sscanf(lines[i]->c_str(), "f %d//%d %d//%d %d//%d", v1, vn, v2, vn, v3, vn);

sscanf expects to be given the address to store the value it has parsed from the string. These calls here pass the uninitialized values of v1, vn etc. as the address, resulting in sscanf writing the results to random places in memory.

This should get you closer to your goal:

sscanf(lines[i]->c_str(), "f %d//%d %d//%d %d//%d", &v1, &vn, &v2, &vn, &v3, &vn);

(I notice that '&vn' is passed multiple times here, which may not be what is intended)

Upvotes: 1

Related Questions