0

I am new to c++, i am on a check scanner's project and i am using an API that was provided with the scanner. Here's my code:

.h file :

#include <iostream>
#include<Windows.h>
#include<vector>

using namespace std;
class Excella
{
public:
    vector<char*> getDevicesName();
};

.cpp file :

    vector<char*> Excella::getDevicesName()
    {
        DWORD dwResult;
        vector<char*> listeDevices;
        char pcDevName[128]="";
        int i = 6;

// the device's name is stored in the variable 'pcDevName'
        while ((dwResult = MTMICRGetDevice(i, (char*)pcDevName)) != MICR_ST_DEVICE_NOT_FOUND) {
            dwResult = MTMICRGetDevice(i, (char*)pcDevName);
            i++;
            listeDevices.push_back((char*) pcDevName);
        }
        return listeDevices;
    }

main.cpp

vector<char*> liste = excella.getDevicesName();
        if (liste.empty()!= true)
        {
            for (vector<char*>::iterator IterateurListe = liste.begin(); IterateurListe != liste.end(); ++IterateurListe)
            {   string str(*IterateurListe);
                auto managed = gcnew String(str.c_str());
                devices->Items->Add(managed);
            }
        }
        else {
            MessageBox::Show("The vector is empty");
        }

The problem is that i can get the right device number.. i just have some weird caracters.

Thank u for ur help.

6
  • Can you give a little more detail? What kind of weird characters are you getting? Commented Jan 20, 2016 at 10:33
  • For one pcDevName is already a char* so get rid of the unneeded char* cast. Commented Jan 20, 2016 at 10:35
  • For two, you never check the result of dwResult to make sure ` MTMICRGetDevice was successful before pushing the pcDevName into the vector; if it failed, that would explain why you see uninitialized garbage. Commented Jan 20, 2016 at 10:37
  • For three, pcDevName should be reinitialized each loop instead of being reused. Commented Jan 20, 2016 at 10:38
  • Use a debugger; it saves lives. Commented Jan 20, 2016 at 10:39

2 Answers 2

1

That's not surprising.

char pcDevName[128]=""; will go out of scope at the end of of the function vector<char*> Excella::getDevicesName(). So any pointers to this that you've pushed to the vector will no longer be valid. Formally speaking, the behaviour of your program is undefined.

It's far simpler to use std::vector<std::string> instead. Remarkably, that's the only change you'd have to make: push_back((char*) pcDevName) will take a value copy of pcDevName (that's how the std::string constructor works). Drop the unnecessary (char*) casts though.

Sign up to request clarification or add additional context in comments.

Comments

1

Here:

listeDevices.push_back((char*) pcDevName);

you are pushing into listeDevices a pointer to stack array. There are two problems with this - mayor one is that once your getDevicesName function ends, those pointers are invalid and use of them is Undefined, the other is that in each iteration of your loop you overwrite pcDevName and also your stored pointer content.

What you should do is to make listeDevices store std::string, ie. std::vector<std::string>, and then you can use listeDevices.push_back((char*) pcDevName); to safely store your names in a vector.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.