Return statement breaking my function c++ - c++

So I call a function in main:
B.remove()
Which goes here
m_arrays[m_oldest]->remove()
Then finally here:
int MyClass::remove() {
cout << "this is the remove function"<< endl; //debugging line
int lastVal = 0;
for (int i = start; i < capacity; i++) { //actual remove function
if (m_array[i] != NULL) {
int lastVal = m_array[i];
m_array[i] = NULL; // sets to null
m_size--; //increment
break;
}
}
m_start++; //increment
return lastVal;
}
If I remove the code containing lastVal, the function works properly. Why is this? Is there an easy way to fix this?
As you can see I'm attempting to return a value before removing it from the array. I am aware I should be using vector or some other standard method, but I cannot. I looked in my textbook but I couldn't find what I was looking for. Any help is greatly appreciated.

You have two int lastVal statements in your code - one before the for loop and one in it. Try removing the declaration inside the for loop (and set it to the assignment lastVal = m_array[i];) and see if it works.

Related

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

How to find a certain value in a vector of strings

I'm trying to create a program for an assignment that will add and remove strings from a vector of strings, but first I need to create a function that will find whether or not the string already exists in the vector.
I've already tried to use a loop to search through the vector to find a specific desired string at each index. I tried adding a break; to exit if the string was found. I don't know if the function is supposed to be void or boolean.
bool FindString(int vctrSize, vector<string> restaurantVctr, string targetRestnt) {
int i;
for (i = 0; i < vctrSize; ++i) {
if (restaurantVctr.at(i) == targetRestnt) {
return true;
break;
}
else {
return false;
}
}
}
I expect the output to be true if the string was found, else it would obviously be false.
Edit: I forgot to mention that I also received the warning: "not all control paths return a value"
You should use std algorithms whenever possible:
auto result = std::find(restaurantVctr.begin(), restaurantVctr.end(), targetRestnt);
return result != restaurantVctr.end();
That is exactly what std::find is for.
While I recommend using std::find as others have recommended, if you're curious what is wrong with your code, the problem is your else:
for (i = 0; i < vctrSize; ++i) {
if (restaurantVctr.at(i) == targetRestnt) {
return true;
break;
}
else {
return false;
}
}
If the first item in your vector is not equal to targetRestnt, then your function returns--that is, it ends execution.
You only want to return false if it's not in the whole list--that is, you want the whole loop to execute:
for (i = 0; i < vctrSize; ++i) {
if (restaurantVctr.at(i) == targetRestnt) {
return true;
// Also, you don't need a break here: you can remove it completely
// For now, I just commented it out
// break;
}
}
// We didn't find it:
return false;

c++ making an array null using foreach

Node* nodes[3];
for (Node* eachNode:nodes) {
eachNode = 0; //if i try to dereference it gives seg fault
} // eg. *eachNode = 0;
if (nodes[0] == 0) {
cout << "Null";
} else
cout << "Not null";
cout << '\n';
Node* nodes2[3];
for (int i = 0; i < 3; ++i) { //this way works fine
nodes2[i] = 0;
}
if (nodes2[0] == 0) {
cout << "Null";
} else
cout << "Not null";
Hi guys I am trying to make all my objects in an array equal to null. When using a for loop it works fine but when I use a foreach loop it breaks.
The output i get is
Not null
Null
I think i have to dereference the nodes in the foreach loop but it gives a seg fault.
Does anyone know whats wrong? thanks.
The loop you wrote loops over the values of the array:
for (Node* eachNode:nodes) {
eachNode = 0;
}
The above loop could as well have been written using auto:
for (auto eachNode:nodes) {
eachNode = 0;
}
The problem with the above loops is that eachNode is not the pointer stored in the array, but a copy of that pointer stored in a local variable of the loop.
If you wish to set the node to null, you need a reference to the memory location where you want to set it. You get that reference by referring to the array element using auto&:
for (auto& eachNode:nodes) {
eachNode = 0;
}
This last segment will likely do what you want.
I believe instead you should try:
for(Node *&eachNode : nodes) {
eachNode = nullptr;
}
This way you get a reference as opposed to the value, and you can appropriately set it to nullptr.
I'm not super experienced in C++ 11, but I did have a read here for more information about this new range construct.
Pointers are passed by value. So setting the eachNode = 0; will change the value, otherwise you are trying to dereference sonething that isn’t a pointer.

Segmentation Error C++

I am fairly new to the C++ language and I am trying to write a recursive method to traverse a tree. I have a traverse method but there is one line of code that causes a segmentation fault. I have tested this by commenting and uncommenting the line, compiling and executing. I have researched why segmentation errors are caused and do not see why any of what I am doing is causing a problem with the memory. Can someone give me advice about what I am doing wrong?
map<int, Node> theNodes;
void initialize()
{
// first we read the data
while (inStream.hasNext())
{
string nextLine = inStream.nextLine();
Node newNode = Node(nextLine);
this->theNodes[newNode.getSequence()] = newNode;
}
}
Code for getDownLinks() and getSequence
vector<int> downLinks;
int sequence;
vector<int> Node::getDownLinks() const
{
return this->downLinks; //
}
int Node::getSequence() const
{
return this->sequence;
}
Traversal Class Code
int totalPayoff;
Node headNode;
int Traversal::traverse()
{
Node headNode = theNodes[0];
std::vector<int> downLinks = headNode.getDownLinks();
for(int i = 0; i < downLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[downLinks[i]];
traverseInner(a, currentNode);
}
return this->totalPayoff;
}
Here is the traverseInner function
int Traversal::traverseInner(int& level, Node& node)
{
std::vector<int> nodeDownLinks = node.getDownLinks();
if(nodeDownLinks.size() == 0)
{
totalPayoff = totalPayoff + node.getPayoff();
return 0;
}
for(int i = 0; i < nodeDownLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[nodeDownLinks[i]]; <-- This causes segmentation error.
traverseInner(a, currentNode);
}
return totalPayoff;
}
Any variables that are not declared here are declared in the header file. The code compiles fine.
I'd also like to mention that I have written this code in many different ways and through my observations have come to the conclusion that any variable that is trying to be accessed in the braces of a nested statement cannot be accessed by the memory. Even the int a variable that is declared right above the problem statement and even hard coded data which is supposed to be there such as nodeDownLinks. If I try to print out through standard output the size of the vector inside one of the nested statements, I also get a segmentation error.
Probably the value inside "nodeDownLinks[i]" it is not initialized, having a memory random value, then you are trying to access this position in the
"theNodes" array and gives to you the segmentation fault.
Please, be sure the values inside "nodeDownLinks" are initialized.
99% it crashes because theNodes has less size, then nodeDownLinks[i] contains index. So nodeDownLinks[i] contains wrong index, u'd better check it and print what goes wrong this way:
int a = 0;
int link = nodeDownLinks[i];
if (theNodes.size() <= link)
std::err << "Wrong link " << link << " in Node" << std::endl;
else
traverseInner(a, theNodes[link]);
It shouldnt crash and you can find wrong index in nodeDownLink easily!

Indexing my while loop with count parameter in an array

My function takes an array of ifstream ofjects and the number of ifstream objects as seen below:
void MergeAndDisplay(ifstream files[], size_t count)
My problem is I want to use a while loop to read from the file(s) as long as one of them is open. When I get to eof, I close the file. So I thought I could do something like
int fileNum = 0;
while(files[fileNum].is_open() || something here) {
//do stuff
}
But I am not really sure how to put the correct amount of parameters in my while loop...
You will have to compute the logic of "is any file in this set open" separately. I suggest making it its own function so that the while loop can be clean and natural, e.g.
bool isAnyOpen(ifstream files[], size_t count) {
for (size_t i = 0; i < count; ++i) {
if (files[i].is_open()) return true;
}
return false;
}
Then you can write
while(isAnyOpen(files, count)) {
// Your code here
}
Edit: This is a more general case solution than what R Samuel Klatchko posted. If your problem is as simple as wanting to just read all the data out of all the files, then use his method since it is more direct.
You probably want
while (fileNum < count && files[fileNum].is_open())
with the condition that you increment fileNum whenever you open a new file in your loop.
Try something like this:
void ProcessStream(std::istream& input_file)
{
//...
}
// Your loop
bool a_file_is_open = true;
do
{
a_file_is_open = false;
for (unsigned int i = 0; i < MAX_FILES; ++i)
{
if (files[i].is_open())
{
a_file_is_open = true;
ProcessStream(files[i]);
break;
}
}
} while (a_file_is_open);