c++ scandir is filling my memory up - c++

I use a function I implemented in my class:
bool MyClass::getNextFile(string& s_first_file, const char* c_path_data){
//string s_first_file = "";
struct dirent **namelist;
string s_file_actual = "";
int n;
int i=0;
n = scandir(c_path_data, &namelist, dataFilter, alphasort);
if (n < 0){
//perror("scandir");
return false;
}else{
while (i<n) {
s_file_actual = namelist[i++]->d_name;
if(i==1){
cout << "get file " << s_file_actual << "..." << endl;
s_first_file = s_file_actual;
}
}
free(namelist[i-1]);
return true;
}
}
In my c++ programm I use the following:
...
MyClass myc;
...
int main(){
while(myc.getNextFile(s_first_file, c_path_data)){
s_first_file << endl;
}
return 1;
}
What happens is that my ram memory get fuller and fuller as long as the function is called every time again.
If I put the code directly it in the main It searches the next first occouring file and don't collect that much memory.
Any hint what I am missing here?
Thank you very much.

You should do something like this;
while (i<n)
{
s_file_actual = namelist[i++]->d_name;
if (i==1)
{
cout << "get file " << s_file_actual << "..." << endl;
s_first_file = s_file_actual;
}
free(namelist[i-1]);
}
free(namelist);
return true;

while (i<n) {
s_file_actual = namelist[i++]->d_name;
if (i==1) {
cout << "get file " << s_file_actual << "..." << endl;
s_first_file = s_file_actual;
}
}
free(namelist[i-1]);
return true;
Whoops!
I'm not sure how it happened, but you put your free in the wrong place and forgot the other one.
Per the manpage, you need to free(namelist[i-1]) inside the loop … and perform a free(namelist) at the end.

Related

No variable declared as function, but Error: invalid operands to binary expression

I'm trying to write a program to delete leading spaces in a poorly formatted C++ program. I get this error in line 24: cout << removeLeadingSpaces(s) << endl;, please help.
#include <iostream>
using namespace std;
string removeLeadingSpaces(string line)
{
bool start = false;
string newline;
for (int i = 0; i < line.size(); i++)
{
if (!isspace(line[i]) && start==false)
{
start = true;
}
if (start==true)
newline += line[i];
}
return newline;
}
void printindented()
{
string s;
while (getline(cin, s))
cout << removeLeadingSpaces(s) << endl;
}
int main()
{
cout << printindented() << endl;
}
The problematic line is
cout << printindented() << endl;
in main. The line
cout << removeLeadingSpaces(s) << endl;
in printindented is just fine.
Change the line in main to:
printindented();
In int main you're trying to print a function that returns void which is causing the error. Also you should use proper indentation and next time word your question a bit better by giving more insight into the problem.
Fixed code
int main()
{
printindented(); // Can't print void cout << printindented() << endl;
}

Infinity Loop in Lexical Analyzer in C++

int main(int argc, char *argv[]) {
ifstream inFile;
int numOfLines = 0, numOfTokens = 0, numOfStrings = 0, maxStringLength = 0, l = 0, fileCount=0, mostCommonCount=0;
string inputFile, mostCommonList="", word;
for(int i = 1; i < argc; i++){
if(strpbrk(argv[i] , "-")){
if(flags.find(string(argv[i]))!=flags.end()) flags[string(argv[i])] = true;
else{
cerr << "INVALID FLAG " << argv[i] << endl;
exit(1);
}
}
else{
inFile.open(argv[i]);
fileCount++;
if(!inFile && fileCount==1){
cerr << "UNABLE TO OPEN " << argv[i] << endl;
exit(1);
}
else{
string line;
while(getline(inFile, line)) inputFile+=line+='\n';
if(fileCount>1){
cerr << "TOO MANY FILE NAMES" << endl;
exit(1);
}
}
}
}
int linenum = 0;
TType tt;
Token tok;
while((tok = getNextToken(&inFile, &linenum))!=DONE && tok != ERR){
tt = tok.GetTokenType();
word = tok.GetLexeme();
if(flags["-v"]==true){
(tt == ICONST||tt==SCONST||tt==IDENT) ? cout<<enumTypes[tok.GetTokenType()]<<"("<< tok.GetLexeme()<<")"<<endl : cout<< enumTypes[tok.GetTokenType()]<<endl;
}
if(flags["-mci"]==true){
if(tt==IDENT){
(identMap.find(word)!=identMap.end()) ? identMap[word]++ : identMap[word]=1;
if(identMap[word]>mostCommonCount) mostCommonCount = identMap[word];
}
}
if(flags["-sum"]==true){
numOfTokens++;
if(tt==SCONST){
numOfStrings++;
l = word.length();
if(l > maxStringLength) maxStringLength = l;
}
}
}
if(tok==ERR){
cout << "Error on line" << tok.GetLinenum()<<"("<<tok.GetLexeme()<<")"<<endl;
return 0;
}
if(flags["-mci"]==true){
cout << "Most Common Identifier: ";
if(!identMap.empty()){
word ="";
for(auto const& it : identMap){
if(it.second==mostCommonCount) word += it.first + ",";
}
word.pop_back();
cout << word << endl;
}
}
if(flags["-sum"]){
numOfLines = tok.GetLinenum();
numOfLines = tok.GetLinenum();
cout << "Total lines: " << numOfLines << endl;
cout << "Total tokens: " << numOfTokens << endl;
cout << "Total strings: " << numOfStrings << endl;
cout << "Length of longest string: " << maxStringLength << endl;
}
inFile.close();
return 0;
}
For some reason this code is running infinitely. I cannot figure out the source of error. I also do not know whether this file or the other linked file is causing this error so I posted the main program code. I think is one of the switch statements that causing this error but I am not sure. FYI: I am supposed to make a lexical analyzer so I had three files one lexigh.h (contains all the data types and all the functions), getToken.cpp(file that defines the functions from lexigh.h) and the main program which calls the methods and tests it.

Negative value not being added to Array

Problem
I have 2 arrays, one for positive numbers, one for negative numbers. For some reason, if the first number to be added is a negative number, it creates the array space to add the number yet the number inserted will always be 0.
Code for adding
Here is my add method, it determines if the value is negative or positive and adds the value to the appropriate array:
bool MyClass::addInt(int valueToBeInserted){
if (valueToBeInserted >= 0){
if (posArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myPArray[posArrayIterator] = valueToBeInserted;
posArrayIterator ++;
return true;
}
} else {
if (negArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myNarray[negArrayIterator] = valueToBeInserted;
negArrayIterator ++;
return true;
}
}
}
Output
With the following test:
b.addInt(-1);
b.addInt(-3);
b.addInt(-9);
The expected output would be
[-1, -3, -9]
but output is
[-3, -9, 0].
Any help is much appreciated.
Since you are not posting the whole class I can only guess where the problem is.
1) Are posArrayIterator and negArrayIterator initialized to 0? They should be!
2) What is a value of sizeOfMyArray?
There is nothing wrong with your bool MyClass::addInt(int valueToBeInserted)
See example below:
class MyClass
{
private:
int sizeOfMyArray;
int posArrayIterator;
int negArrayIterator;
int myNarray[20];
int myPArray[20];
public:
MyClass(){
sizeOfMyArray = 20;
posArrayIterator = 0;
negArrayIterator = 0;
};
bool addInt(int value);
void printNArray()
{
cout << "[ ";
for (int i=0; i<negArrayIterator; i++)
{
cout << myNarray[i];
if ( (i+1) < negArrayIterator )
{
cout << ", ";
}
}
cout << "]";
}
};
bool MyClass::addInt(int valueToBeInserted){
if (valueToBeInserted >= 0){
if (posArrayIterator >= sizeOfMyArray){
return false;
} else {
cout << "added " << valueToBeInserted << "\n" << endl;
myPArray[posArrayIterator] = valueToBeInserted;
posArrayIterator ++;
return true;
}
} else {
if (negArrayIterator >= sizeOfMyArray){
return false;
}
else {
cout << "added " << valueToBeInserted << "\n" << endl;
myNarray[negArrayIterator] = valueToBeInserted;
negArrayIterator ++;
return true;
}
}
}
int main()
{
MyClass b;
b.addInt(-1);
b.addInt(-3);
b.addInt(-9);
b.printNArray();
return 0;
}
Output:
added -1
added -3
added -9
[ -1, -3, -9]

For loop not accessing and performing check

I am having some troubles with one of my for loops not executing correctly. I have stepped through my code to try and see what's going on but it just seems to skip the for loop completely therefore giving the incorrect output.
My for loop looks like this:
for (auto &link : p1links){
if (link->accessTransportType() != type){
continue;
}
if ((p1->accessReference() == link->accessReferenceNumber1() && p2->accessReference() == link->accessReferenceNumber2()) || (p1->accessReference() == link->accessReferenceNumber2() && p2->accessReference() == link->accessReferenceNumber1()))
{
anyPASS = true;
}
}
if (anyPASS){
m_outFile << p1->accessReference() << "," << p2->accessReference() << "," << "PASS" << endl;
return true;
}
else{
m_outFile << p1->accessReference() << "," << p2->accessReference() << "," << "FAIL" << endl;
return true;
break;
}
}
m_outFile << endl;
And these are the methods its trying to access when I say accessTransportType() etc.
class Links
{
public:
Links(int, int, const string&, bool);
~Links();
int accessReferenceNumber1()const{ return referenceNumber1; }
int accessReferenceNumber2()const{ return referenceNumber2; }
string accessTransportType()const{ return transportType; }
bool accessHasBeenSearched()const{ return hasBeenSearched; }
private:
int referenceNumber1 = 0;
int referenceNumber2 = 0;
string transportType = "";
bool hasBeenSearched = false;
};
My output is currently returning the FAIL every time but I am looking to return PASS for my first check and then a FAIL when it does the second check.

Seg Fault - Signal received, SIGABORT

So my code compiles well, but whenever I try running the program, it seg faults. I ran it through gdb and got this set of error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Program received signal SIGABRT, Aborted.
0x00007ffff722bcc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Here is my code if it helps:
using namespace std;
#include <iostream>
#include <vector>
#include <cmath>
#include<fstream>
#include <cstdlib>
#include <utility>
#include <string>
class Page
{
public:
int TimeStamp;
int ProgramOwner;
int LocalPageNumber;
};
//Pair: first entry is local page, second entry is global page
//Second entry: 1 if in main memory, 0 if not
class Program
{
public:
vector< pair<int,int> > MemoryMap;
};
class Memory
{
public:
vector<Program> Programs;
vector<Page> Pages;
};
void checkArguments(int argc, char *argv[]);
bool checkPageAlgorithm(char *argv[]);
bool checkPageSize(int pagesize);
bool checkPageStyle(char *argv[]);
bool checkPTrace(string ProgramTraceFile);
bool checkPList(string ProgramListFile);
int main(int argc, char *argv[])
{
//checkArguments(argc, argv);
const int MemSize = 512;
int pageSize = atoi(argv[3]);
string programListFile = argv[1];
string ProgramTraceFile = argv[2];
string pageAlgorithm = argv[4];
string pageStyle = argv[5];
int programNumber;
int programSize;
int PagesNeeded;
Memory MainMemory;
int numberFrames;
int pageFaults = 0;
int numPrograms = 0;
int PagesPerProgram;
int LocalPage;
int activeProgram;
int requestedLocation;
int newPageLocation;
bool foundInMemory;
ifstream fileIn;
fileIn.open(programListFile.c_str());
if(fileIn.fail())
{
cerr << "List file not found." << endl;
fileIn.close();
exit(1);
}
else
{
while(!fileIn.eof())
{
cout << "hey0";
fileIn >> programNumber;
fileIn >> programSize;
numPrograms++;
}
}
numberFrames = ceil(MemSize/pageSize);
PagesPerProgram = ceil(numberFrames/numPrograms);
MainMemory.Pages.resize(numberFrames);
cout << "hey1";
while(!fileIn.eof())
{
cout << "hey2";
fileIn >> programNumber;
fileIn >> programSize;
cout << "hey3";
PagesNeeded = ceil(programSize/pageSize);
for(int i = 0; i < PagesNeeded; i++)
{
LocalPage = i;
MainMemory.Pages[i].ProgramOwner = programNumber;
MainMemory.Pages[i].LocalPageNumber = LocalPage;
}
cout << "hey3";
if(PagesNeeded > PagesPerProgram)
PagesNeeded = PagesPerProgram;
for(int i = 0; i < PagesNeeded; i++)
{
MainMemory.Programs[programNumber].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
MainMemory.Programs[programNumber].MemoryMap[i].second = 1;
if(pageAlgorithm == "clock")
MainMemory.Pages[i].TimeStamp = 1;
else
MainMemory.Pages[i].TimeStamp = 0;
}
}
fileIn.close();
//LRU Algorithm Implementation
if(pageAlgorithm == "lru")
{
cout << "here1";
fileIn.open(ProgramTraceFile.c_str());
if(fileIn.fail())
{
cerr << "That file does not exist." << endl;
fileIn.close();
exit(1);
}
else
{
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
while(!fileIn.eof())
{
foundInMemory = false;
for(int i = 0; i < static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()); i++)
{
if((MainMemory.Programs[activeProgram].MemoryMap[i].second == 1) &&
(MainMemory.Programs[activeProgram].MemoryMap[i].first == newPageLocation))
foundInMemory = true;
if(foundInMemory)
break;
}
if(!foundInMemory)
{
pageFaults++;
if(static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) < PagesPerProgram)
{
pair<int, int> temp;
temp.first = newPageLocation;
temp.second = 1;
MainMemory.Programs[activeProgram].MemoryMap.push_back(temp);
}
else
{
for(int i = 0; i < (static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) - 1); i++)
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = newPageLocation;
}
if(pageStyle == "1")
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
}
}
MainMemory.Pages[i].TimeStamp++;
}
}
}
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
}
}
}
cout << "------------------------------------" << endl;
cout << "Page Size: " << pageSize << endl;
cout << "Page Replacement Algorithm: " << pageAlgorithm << endl;
cout << "Paging Style: ";
if(pageStyle == "0")
cout << "Demand" << endl;
else
cout << "Prepaging" << endl;
cout << "Number of Page Faults: " << pageFaults << endl;
cout << "------------------------------------" << endl;
return 0;
}
bool checkPList(string programlistfile)
{
ifstream ListFile(programlistfile.c_str());
if(ListFile.fail())
{
cerr << "Cannot find file " << programlistfile << endl;
ListFile.close();
return false;
}
else
{
ListFile.close();
return true;
}
}
bool checkPTrace(string programTraceFile)
{
ifstream TraceFile;
TraceFile.open(programTraceFile.c_str());
if(TraceFile.fail())
{
cerr << "Cannot find file " << programTraceFile << endl;
TraceFile.close();
return false;
}
else
{
TraceFile.close();
return true;
}
}
bool checkPageStyle(string pageStyle)
{
if(pageStyle == "0")
return true;
else if(pageStyle == "1")
return true;
else
{
cerr << "Page Style can be: 0 or 1." << endl;
return false;
}
}
bool checkPageSize(int pagesize)
{
bool isValid = false;
switch(pagesize)
{
case 1:
isValid = true;
break;
case 2:
isValid = true;
break;
case 4:
isValid = true;
break;
case 8:
isValid = true;
break;
case 16:
isValid = true;
break;
default:
cerr << "Page Size can be: 1, 2, 4, 8, or 16." << endl;
isValid = false;
}
return isValid;
}
bool checkPageAlgorithm(string pageAlgorithm)
{
if(pageAlgorithm == "lru")
return true;
else if(pageAlgorithm == "fifo")
return true;
else if(pageAlgorithm == "clock")
return true;
else
{
cerr << "Valid Page Algorithms are: lru, fifo, or clock" << endl;
return false;
}
}
void checkArguments(int argc, char *argv[])
{
if(argc < 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(argc > 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(!checkPageAlgorithm(argv[4]))
exit(1);
else if(!checkPageSize(atoi(argv[3])))
exit(1);
else if(!checkPageStyle(argv[5]))
exit(1);
else if(!checkPTrace(argv[2]))
exit(1);
else if(!checkPList(argv[1]))
exit(1);
return;
}
The output 'heys' are just to see if they get triggered within gdb, which they don't.
You forgot to actually ask any question.
Presumably, your question is "why does my program die with SIGABRT?"
The answer was provided by the program itself: you've tried to construct std::string from a NULL character pointer, which throws std::logic_error exception (because it's not a valid thing to do).
You may have a follow-up quesiton: "where in my program does this happen?".
You could find the answer by using GDB where command. As a first guess, you didn't invoke your program with sufficient number of arguments. For example, if you did this:
gdb ./a.out
(gdb) run
then argv[1] is NULL, and this statement:
string programListFile = argv[1];
would throw the exception you are getting.
The common solution to this problem is to insist that you do have correct number of arguments, e.g. put this:
if (argc < 6) {
std::cerr << "Not enough arguments" << std::endl;
return 1;
}
at the start of main. Or just comment the call to checkArguments() back in.