running code doesn't work when being used in dll - c++

I'm programming in c++ in Visual Studio.
This is my subroutine, which gives me a specific value back from a double array:
double specific_value_search(std::string mol_fractions_name[], std::string mass_fractions_name_output[], double mass_fractions_output[], int molecule)
{
double specific_value=5;
std::string a = mol_fractions_name[molecule];
std::string b;
for (int i = 0; i <= 11; i++)
{
b = mass_fractions_name_output[i];
if (a.compare(b) == 0)
//if ((a.find(b) != std::string::npos))...this was my second try // sollte string b in Zeile a gefunden werden, dann...
{
specific_value = mass_fractions_output[i];
break;
}
}
return specific_value;
}
so when I execute this code in my project to an .exe, the code runs fine.
but when I compile it to an dll, an run it via an external program, the value returns 5, because of my initalisation (without initialisation the program crashes because of trying to return an uninitialized variable.
I added the values from visual studio in the screenshots below
Does anyone have any advice?
Screenshot 1 - values from visual studio
Screenshot 2 - values from visual studio

If you can use a standard container (std::map or std::unsorted_map) then this becomes trivial.
std::map<std::string, double> fractionNames;
// fill map
double specificValue = fractionNames[mol_fractions_name[molecule]];
If it's possible that molecule is bigger than the number of names or that you need to generate an error if the fraction name isn't found in the map then you'll have to add some code to detect and handle these situations.
If you can't use a map, then you could use a vector
struct FractionName {
std::string name;
double value;
}
typedef std::vector<FractionName> FractionNameVector;
FractionNameVector fractionNames;
// again fill fractionNames
FractionNameVector::iterator iter = std::find(fractionNames.begin(), fractionNames.end(), SearchPredicate(mol_fractions_name[molecule]));
This will need a SearchPredicate like this
struct SearchPredicate
{
bool operator()(const FractionName& haystack) { return haystack.name ==
needle; }
explicit SearchPredicate(const std::string name) : needle(name) {}
std::string needle;
};
You could use a lambda if you are using C++11 or later.

Related

Strange Error with Vectors in C++

Every time I compile the code for a RTS Project I am working on, I get this error:
error C2664: 'std::_Vector_iterator<_Ty,_Alloc> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Ty,_Alloc>)' : cannot convert parameter 1 from 'MAPTILE *' to 'std::_Vector_const_iterator<_Ty,_Alloc>'
The code area that I have for this method is this:
MAPTILE *startTile = GetTile(start);
MAPTILE *goalTile = GetTile(goal);
...
std::vector<MAPTILE*> open; //Create Our Open list
startTile->g = 0; //Init our starting point (SP)
startTile->f = H(start, goal);
startTile->open = true;
open.push_back(startTile); //Add SP to the Open list
bool found = false; // Search as long as a path hasnt been found,
while(!found && !open.empty()) // or there is no more tiles to search
{
MAPTILE * best = open[0]; // Find the best tile (i.e. the lowest F value)
int bestPlace = 0;
for(int i=1;i<open.size();i++)
if(open[i]->f < best->f)
{
best = open[i];
bestPlace = i;
}
if(best == NULL)break; //No path found
open[bestPlace]->open = false;
open.erase(&open[bestPlace]); // Take the best node out of the Open list
I have searched on this website and a few others, but I could not find the correct area.
I am reading "Programming a RTS Game With Direct3D" By Carl Granberg.
All of my code is right because I matched it with the source code, and I got the same error.
I am using Visual C++ 2008 Express Edition.
I have never gotten this error before.
erase wants an iterator and you are giving it a pointer to an element within the array. Use std::advance or keep a handle to an iterator.
std::vector<MAPTILE*> p = open.begin();
std::advance(p, bestPlace);
open.erase(p);
EDIT I forgot that std::advance doesn't return anything. Sorry about that. I haven't done serious C++ development for about five years.
I would rewrite your for loop to use iterators instead of indexes.
I believe that the following snippet is equivalent to your snippet after replacing the array indexing with iterators. I had to add the typedef to make it more readable.
MAPTILE *startTile = GetTile(0);
startTile->g = 0;
startTile->f = H(0, 10);
startTile->open = true;
std::vector<MAPTILE*> open;
open.push_back(startTile);
typedef std::vector<MAPTILE*>::iterator Iterator;
bool found = false;
while (!found && !open.empty()) {
Iterator best = open.begin();
for (Iterator iter=best+1, end=open.end();
iter!=end; ++iter)
{
if ((*iter)->f < (*best)->f) {
best = iter;
}
}
if (*best == NULL) {
break;
}
(*best)->open = false;
open.erase(best);
}
I'm not completely convinced that the if (*best == NULL) condition will ever be matched though. This compiles without error under clang++ (sorry, no visual studio in my house). When I run your snippet through clang++, I get comparable failures to yours:
foo.cpp:85:14: error: calling a private constructor of class
'std::__1::__wrap_iter<MAPTILE *const *>'
open.erase(&open[bestPlace]);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/iterator:1381:31: note:
declared private here
_LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_D...
^
1 error generated.
I don't know what else to say, std::vector<>::erase takes a std::vector<>::iterator parameter and that's all that there is to it. My guess is that the book was written against a version of VC++ that used pointers for vector iterators though I don't recall one that ever did that.

Values of the function parameters are changing randomly (but they're not modified from the code)

I have to implement an NBC (for finding clusters in the provided set of data) algorithm at my class project with a friend. We came across very strange issue. There are few helper functions, and the one with a problem is kNN (possibly kEN too) in the kNB.h file. After passing arguments to it from the main function of the program (for example k=3 and p=5), it goes to the kNN function and starts changing values of k and p randomly, even though function code is not supposed to do that anywhere as you can see below.
Also, while using debugging mode and going through this function step by step I noticed that it sometimes comes back before the first while which I think shouldn't happen. I guess it may be some trivial mistake, but I'm not very good at C++ (unfortunately we were ordered to use it). You can download entire Visual Studio 2013 solution from here: https://dl.dropboxusercontent.com/u/1561186/EDAMI.zip. So, does anyone have any idea why described situation is happening?
static vector<int> kNN(int k, int p, Dataset<V>* records)
{
int b = p, f = p;
bool backwardSearch, forwardSearch;
vector<int> tmp;
LengthMetric<V>* lengthMetric = records->getLengthMetric();
backwardSearch = PrecedingPoint(records, b);
forwardSearch = FollowingPoint(records, f);
int i = 0;
while (backwardSearch && forwardSearch && i < k)
{
if (records->getRecord(p)->getLength() - records->getRecord(b)->getLength() < records->getRecord(f)->getLength() - records->getRecord(p)->getLength())
{
i++;
tmp.push_back(b);
backwardSearch = PrecedingPoint(records, b);
}
else
{
i++;
tmp.push_back(f);
forwardSearch = FollowingPoint(records, f);
}
}
while (backwardSearch && i < k)
{
i++;
tmp.push_back(b);
backwardSearch = PrecedingPoint(records, b);
}
while (forwardSearch && i < k)
{
i++;
tmp.push_back(f);
forwardSearch = FollowingPoint(records, f);
}
return tmp;
}
Look at second constructor of your class Dataset
Dataset(vector<Record<V>*> rrecords,
LengthMetric<V>* metric = new DumbLengthMetric<V>())
: records(rrecords),
lengthMetric(lengthMetric) { // <-------------------
lengthMetric(lengthMetric) does nothing. Changing it to lengthMetric(metric) I got some result on your project and no one variable was changed.
BTW, do not include in zip any stuff like folders Debug, Release and files *.sdf, *.ncb

To find duplicate entry in c++ using 2D Vector (std::vector)

I wrote a program to find duplicate entry in a table. I am a beginner in C++, hence I don't know how this program is working efficient. Is there any other idea to write this program? Here I have 3 tables (2D Vector), that they are 1)aRecord_arr 2)mainTable and 3)idxTable. idxtable is use to identify the keys to check duplicate entry. aRecord_arr table to be add in maintable. If it is already exist in maintable, it will show the error "Duplicate Entry". So Check this program, and give your suggestions.
typedef vector<string> rec_t;
typedef vector<rec_t> tab_t;
typedef vector<int> cn_t;
int main()
{
tab_t aRecord_arr= { {"a","apple","fruit"},
{"b","banana","fruit"} };
tab_t mainTable = { {"o","orange","fruit"},
{"p","pineapple","fruit"},
{"b","banana","fruit"},
{"m","melon","fruit"},
{"a","apple","fruit"},
{"g","guava","fruit"} };
tab_t idxTable = { {"code","k"},
{"name","k"},
{"category","n"}};
size_t Num_aRecords = aRecord_arr.size();
int idxSize = idxTable.size();
int mainSize = mainTable.size();
rec_t r1;
rec_t r2;
tab_t t1,t2;
cn_t idx;
for(int i=0;i<idxSize;i++)
{
if(idxTable[i][1]=="k")
{
idx.push_back(i);
}
}
for(size_t j=0;j<Num_aRecords;j++)
{
for(unsigned int id=0;id<idx.size();id++)
{
r1.push_back(aRecord_arr[j][idx[id]]);
}
t1.push_back(std::move(r1));
}
for(int j=0;j<mainSize;j++)
{
for(unsigned int id=0;id<idx.size();id++)
{
r2.push_back(mainTable[j][idx[id]]);
}
t2.push_back(std::move(r2));
}
for(size_t i=0;i<t1.size();i++)
{
for(size_t j=0;j<t2.size();j++)
{
if(t1[i]==t2[j])
{
cout<<"Duplicate Entry"<<endl;
exit(0);
}
}
}
}
If you want to avoid duplicate entries in an array, you should consider using a std::setinstead.
What you want is probably a std::map or a std::set
Don't reinvent the wheel, the STL is full of goodies.
You seem to be rooted in a weakly typed language - but C++ is strongly typed.
You will 'pay' the disadvantage of strong typing almost no matter what you do, but you almost painstakingly avoid the advantage.
Let me start with the field that always says 'fruit' - my suggestion is to make this an enum, like:
enum PlantType { fruit, veggie };
Second, you have a vector that always contain 3 strings, all with the same meaning. this seems to be a job for a struct, like:
struct Post {
PlantType kind;
char firstchar;
string name;
// possibly other characteristics
};
the 'firstchar' is probably premature optimization, but lets keep that for now.
Now you want to add a new Post, to an existing vector of Posts, like:
vector<Post> mainDB;
bool AddOne( const Post& p )
{
for( auto& pp : mainDB )
if( pp.name == p.name )
return false;
mainDB.push_back(p);
return true;
}
Now you can use it like:
if( ! AddOne( Post{ fruit, 'b', "banana" } ) )
cerr << "duplicate entry";
If you need speed (at the cost of memory), switch your mainDB to map, like:
map<string,Post> mainDB;
bool AddOne( const Post& p )
{
if( mainDB.find(p.name) != mainDB.end() )
return false;
mainDB[p.name]=p;
return true;
}
this also makes it easier (and faster) to find and use a specific post, like
cout << "the fruit is called " << mainDB["banana"].name ;
beware that the above will cause a runtime error if the post dont exists
As you can see, firstchar was never used, and could be omitted. std::map
has a hash-function-specialization for string keys, and it will probably be
orders of magnitude faster than anything you or I could whip up by hand.
All of the above assumed inclusion of the correct headers, and
using namespace std;
if you dont like using namespace, prepend std:: to all the right places
hope it helps :)

Sorting a file with 55K rows and varying Columns

I want to find a programmatic solution using C++.
I have a 900 files each of 27MB size. (just to inform about the enormity ).
Each file has 55K rows and Varying columns. But the header indicates the columns
I want to sort the rows in an order w.r.t to a Column Value.
I wrote the sorting algorithm for this (definitely my newbie attempts, you may say).
This algorithm is working for few numbers, but fails for larger numbers.
Here is the code for the same:
basic functions I defined to use inside the main code:
int getNumberOfColumns(const string& aline)
{
int ncols=0;
istringstream ss(aline);
string s1;
while(ss>>s1) ncols++;
return ncols;
}
vector<string> getWordsFromSentence(const string& aline)
{
vector<string>words;
istringstream ss(aline);
string tstr;
while(ss>>tstr) words.push_back(tstr);
return words;
}
bool findColumnName(vector<string> vs, const string& colName)
{
vector<string>::iterator it = find(vs.begin(), vs.end(), colName);
if ( it != vs.end())
return true;
else return false;
}
int getIndexForColumnName(vector<string> vs, const string& colName)
{
if ( !findColumnName(vs,colName) ) return -1;
else {
vector<string>::iterator it = find(vs.begin(), vs.end(), colName);
return it - vs.begin();
}
}
////////// I like the Recurssive functions - I tried to create a recursive function
///here. This worked for small values , say 20 rows. But for 55K - core dumps
void sort2D(vector<string>vn, vector<string> &srt, int columnIndex)
{
vector<double> pVals;
for ( int i = 0; i < vn.size(); i++) {
vector<string>meancols = getWordsFromSentence(vn[i]);
pVals.push_back(stringToDouble(meancols[columnIndex]));
}
srt.push_back(vn[max_element(pVals.begin(), pVals.end())-pVals.begin()]);
if (vn.size() > 1 ) {
vn.erase(vn.begin()+(max_element(pVals.begin(), pVals.end())-pVals.begin()) );
vector<string> vn2 = vn;
//cout<<srt[srt.size() -1 ]<<endl;
sort2D(vn2 , srt, columnIndex);
}
}
Now the main code:
for ( int i = 0; i < TissueNames.size() -1; i++)
{
for ( int j = i+1; j < TissueNames.size(); j++)
{
//string fname = path+"/gse7307_Female_rma"+TissueNames[i]+"_"+TissueNames[j]+".txt";
//string fname2 = sortpath2+"/gse7307_Female_rma"+TissueNames[i]+"_"+TissueNames[j]+"Sorted.txt";
string fname = path+"/gse7307_Male_rma"+TissueNames[i]+"_"+TissueNames[j]+".txt";
string fname2 = sortpath2+"/gse7307_Male_rma"+TissueNames[i]+"_"+TissueNames[j]+"4Columns.txt";
vector<string>AllLinesInFile;
BioInputStream fin(fname);
string aline;
getline(fin,aline);
replace (aline.begin(), aline.end(), '"',' ');
string headerline = aline;
vector<string> header = getWordsFromSentence(aline);
int pindex = getIndexForColumnName(header,"p-raw");
int xcindex = getIndexForColumnName(header,"xC");
int xeindex = getIndexForColumnName(header,"xE");
int prbindex = getIndexForColumnName(header,"X");
string newheaderline = "X\txC\txE\tp-raw";
BioOutputStream fsrt(fname2);
fsrt<<newheaderline<<endl;
int newpindex=3;
while ( getline(fin, aline) ){
replace (aline.begin(), aline.end(), '"',' ');
istringstream ss2(aline);
string tstr;
ss2>>tstr;
tstr = ss2.str().substr(tstr.length()+1);
vector<string> words = getWordsFromSentence(tstr);
string values = words[prbindex]+"\t"+words[xcindex]+"\t"+words[xeindex]+"\t"+words[pindex];
AllLinesInFile.push_back(values);
}
vector<string>SortedLines;
sort2D(AllLinesInFile, SortedLines,newpindex);
for ( int si = 0; si < SortedLines.size(); si++)
fsrt<<SortedLines[si]<<endl;
cout<<"["<<i<<","<<j<<"] = "<<SortedLines.size()<<endl;
}
}
can some one suggest me a better way of doing this?
why it is failing for larger values. ?
The primary function of interest for this query is Sort2D function.
thanks for the time and patience.
prasad.
I'm not sure why your code is crashing, but recursion in that case is only going to make the code less readable. I doubt it's a stack overflow, however, because you're not using much stack space in each call.
C++ already has std::sort, why not use that instead? You could do it like this:
// functor to compare 2 strings
class CompareStringByValue : public std::binary_function<string, string, bool>
{
public:
CompareStringByValue(int columnIndex) : idx_(columnIndex) {}
bool operator()(const string& s1, const string& s2) const
{
double val1 = stringToDouble(getWordsFromSentence(s1)[idx_]);
double val2 = stringToDouble(getWordsFromSentence(s2)[idx_]);
return val1 < val2;
}
private:
int idx_;
};
To then sort your lines you would call
std::sort(vn.begin(), vn.end(), CompareByStringValue(columnIndex));
Now, there is one problem. This will be slow because stringToDouble and getWordsFromSentence are called multiple times on the same string. You would probably want to generate a separate vector which has precalculated the values of each string, and then have CompareByStringValue just use that vector as a lookup table.
Another way you can do this is insert the strings into a std::multimap<double, std::string>. Just insert the entries as (value, str) and then read them out line-by-line. This is simpler but slower (though has the same big-O complexity).
EDIT: Cleaned up some incorrect code and derived from binary_function.
You could try a method that doesn't involve recursion. if your program crashes using the Sort2D function with large values, then your probably overflowing the stack (danger of using recursion with a large number of function calls). Try another sorting method, maybe using a loop.
sort2D crashes because you keep allocating an array of strings to sort and then you pass it by value, in effect using O(2*N^2) memory. If you really want to keep your recursive function, simply pass vn by reference and don't bother with vn2. And if you don't want to modify the original vn, move the body of sort2D into another function (say, sort2Drecursive) and call that from sort2D.
You might want to take another look at sort2D in general, since you are doing O(N^2) work for something that should take O(N+N*log(N)).
The problem is less your code than the tool you chose for the job. This is purely a text processing problem, so choose a tool good at that. In this case on Unix the best tool for the job is Bash and the GNU coreutils. On Windows you can use PowerShell, Python or Ruby. Python and Ruby will work on any Unix-flavoured machine too, but roughly all Unix machines have Bash and the coreutils installed.
Let $FILES hold the list of files to process, delimited by whitespace. Here's the code for Bash:
for FILE in $FILES; do
echo "Processing file $FILE ..."
tail --lines=+1 $FILE |sort >$FILE.tmp
mv $FILE.tmp $FILE
done

how to improve natural sort program for decimals?

I have std::strings containing numbers in the leading section that I need to sort. The numbers can be integers or floats.
The vector<std::string> sort was not optimal, I found the following natural sort program which was much better. I still have a small issue with numbers smaller than zero that do not sort just right. Does anyone have a suggestion to improve? We're using Visual Studio 2003.
The complete program follows.
TIA,
Bert
#include <list>
#include <string>
#include <iostream>
using namespace std;
class MyData
{
public:
string m_str;
MyData(string str) {
m_str = str;
}
long field1() const
{
int second = m_str.find_last_of("-");
int first = m_str.find_last_of("-", second-1);
return atol(m_str.substr(first+1, second-first-1).c_str());
}
long field2() const
{
return atol(m_str.substr(m_str.find_last_of("-")+1).c_str());
}
bool operator < (const MyData& rhs)
{
if (field1() < rhs.field1()) {
return true;
} else if (field1() > rhs.field1()) {
return false;
} else {
return field2() < rhs.field2();
}
}
};
int main()
{
// Create list
list<MyData> mylist;
mylist.push_front(MyData("93.33"));
mylist.push_front(MyData("0.18"));
mylist.push_front(MyData("485"));
mylist.push_front(MyData("7601"));
mylist.push_front(MyData("1001"));
mylist.push_front(MyData("0.26"));
mylist.push_front(MyData("0.26"));
// Sort the list
mylist.sort();
// Dump the list to check the result
for (list<MyData>::const_iterator elem = mylist.begin(); elem != mylist.end(); ++elem)
{
cout << (*elem).m_str << endl;
}
return 1;
}
GOT:
0.26
0.26
0.18
93.33
485
1001
7601
EXPECTED:
0.18
0.26
0.26
93.33
485
1001
7601
Use atof() instead of atol() to have the comparison take the fractional part of the number into account. You will also need to change the return types to doubles.
If it's just float strings, I'd rather suggest to create a table with two columns (first row contains the original string, second row is filled with the string converted to float), sort this by the float column and then output/use the sorted string column.
If the data are all numbers I would create a new class to contain the data.
It can have a string to include the data but then allows you to have better methods to model behaviour - in this case espacially to implement operator <
The implementation could also include use of a library that calculates to exact precion e.g. GNU multiple precision this would do the comparison and canversion from string (or if the numbers do not have that many significant figures you could use doubles)
I would compute the values once and store them.
Because they are not actually part of the objects state (they are just calcualted values) mark them as mutable. Then they can also be set during const methods.
Also note that MyClass is a friend of itself and thus can access the private members of another object of the same class. So there is no need for the extranious accessor methods. Remember Accessor methods are to protect other classes from changes in the implementation not the class you are implementing.
The problem with ordering is that atoi() is only reading the integer (ie it stops at the '.' character. Thus all your numbers smaller than 0 have a zero value for comparison and thus they will appear in a random order. To compare against the full value you need to extract them as a floating point value (double).
class MyData
{
private:
mutable bool gotPos;
mutable double f1;
mutable double f2;
public:
/*
* Why is this public?
*/
std::string m_str;
MyData(std::string str)
:gotPos(false)
,m_str(str) // Use initializer list
{
// If you are always going to build f1,f2 then call BuildPos()
// here and then you don't need the test in the operator <
}
bool operator < (const MyData& rhs)
{
if (!gotPos)
{ buildPos();
}
if (!rhs.gotPos)
{ rhs.buildPos();
}
if (f1 < rhs.f1) return true;
if (f1 > rhs.f1) return false;
return f2 < rhs.f2;
}
private:
void buildPos() const
{
int second = m_str.find_last_of("-");
int first = m_str.find_last_of("-", second-1);
// Use boost lexical cast as it handles doubles
// As well as integers.
f1 = boost::lexical_cast<double>(m_str.substr(first + 1, second-first - 1));
f2 = boost::lexical_cast<double>(m_str.substr(second + 1));
gotPos = true;
}
};