Inconsistency between int and bool - c++

I just implemented breadth first search in c++ and instead of declaring a vector as bool, I declared it as an int. This lead to a very odd observation. When I used int, the code printed the following:
1
32763
-524268732
Throughout the entire code, I don't provide any such value to variable as the 2nd and 3rd node receive, so I assume that they are just garbage values, but why do garbage values even come up, when I'm initialising the vector to be full of zeroes ??? You may check the code to be that below:
#include <iostream>
#include <queue>
using namespace std;
queue<int> neigh;
vector< vector<int> > graph(3);
vector<int> flag(3, 0);
int main(void)
{
graph[0].push_back(1); graph[0].push_back(2);
graph[1].push_back(0); graph[1].push_back(2);
graph[2].push_back(0); graph[3].push_back(1);
neigh.push(0);
while(!neigh.empty())
{
int cur = neigh.front();
neigh.pop();
flag[cur] = 1;
for(int i = 0, l = graph[cur].size();i < l;i++)
{
if(!flag[graph[cur][i]])
neigh.push(graph[cur][i]);
}
}
for(int i = 0;i < 3;i++)
{
cout << flag[i] << endl;
}
}
Alright, then I changed just a single line of code, line number 7, the one where I declare and initialise the flag vector.
Before:
vector<int> flag(3, 0);
After:
vector<bool> flag(3, false);
And voila! The code started working:
1 //The new output
1
1
So, my question is, what is the problem with the code in the first place ? I believe it may be some kind of error I made, or possibly that its only by chance that my bfs implementation works at all... So, what is the truth, SO? What is my (possible) mistake ?

You are accessing your vector out of bounds here:
graph[3].push_back(1);
At this moment, graph only has three elements. This leads to undefined behaviour.

Related

Dynamic Programming Using STL Vectors Makes Program Freeze Beyond Certain Values

I wrote the following program, trying to optimize a recursive algorithm using Dynamic Programming.
#include <bits/stdc++.h>
using namespace std;
int mini(int n, vector<int> &memory){
if(n<memory.size()){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
memory[n]=m;
return m;
}
}
int main(){
vector<int> memory={0, 2, 5};
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << mini(n, memory) << "\n";
}
}
The base conditions for the recursive function are already specified inside the vector, and the function does work for the base conditions. It works correctly for mini(1), mini(2), ..., mini(5). Whenever I am trying anything from mini(6) or beyond, the program just freezes.
After a bit of debugging, the problem does seem to be that the function is unable to read any of the values that we are subsequently adding into the memory vector. Which is why the following works:
mini(5) = 6 + mini(2) + mini(2) //mini(2) is pre-specified in memory vector.
mini(4) = 5 + mini(1) + mini(2) //mini(1) and mini(2) are pre-specified.
However,
mini(6) = 7 + mini(2) + mini(3) //mini(3) is not pre-specified into vector memory.
Here, mini(3) should have been added into the vector and used, but the function somehow doesn't seem to be able to do that.
It seems that the function is unable to perform recursions beyond a single level. I have no idea why, and would very much prefer some reason why this is happening.
Following insights from the comments, the problem has been solved.
There were two issues with the initial program:
Trying to insert elements beyond the current size of the vector: To fix this issue, use an if statement before inserting elements to the vector to ensure that it has the correct capacity.
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
Using items from memory that we did not previously insert: When we are resizing memory from the previous point, we are also creating empty values at spots that we did not insert into before. For example, mini(7) would insert the values of mini(3) and mini(7) into memory. The values of mini(4), mini(5) and mini(6) would remain 0. Later when we use the function, the values of mini(4), mini(5) and mini(6) would be found in the memory to be 0, and be used as such, leading to incorrect answers.
Fixing both errors, the revised function looks like this:
int mini(int n, vector<int> &memory){
if(n<memory.size() && memory[n]!=0){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
return m;
}
}

Can' t print position of element in an array after heapify-up C++

Can someone help me with the code in c++ below?
#include <iostream>
#include <fstream>
using namespace std;
int PARENT(int i)
{
return (i/2);
}
int Heapify_up(int arra[], int i)
{
int j,k;
if (i>1){
j = PARENT(i);
if (arra[i]<arra[j]){
k=arra[i];
arra[i]=arra[j];
arra[j]=k;
Heapify_up(arra, j);
}
}
return j;
}
int main()
{
int array3[15];
int i,p,array_length;
ifstream inputFile1("Heapfile.txt");
if (inputFile1.good()){
int current_number = 0;
i=1;
while (inputFile1>> current_number)
array3[i++] = current_number;
inputFile1.close();
}
array_length = i;
cout<<"Please, enter an integer: ";
cin>>p;
array3[array_length+1]=p;
int pos=Heapify_up(array3, array_length+1);
for (i=1; i<15; i++){
cout<<array3[i]<<" ";
}
cout<<"The position is "<<pos;
}
Let me explain you that have an array in a txt file. After i insert a random integer and with the heapify-up algorith I'm sorting this random number to the array. I want to print the new sorted array(I' have done that) and the new position of the random element that i have entered. Any idea?
thanks in advance!
P.S. I am new here and i find it somehow difficult to post my code correctly... still learning! XD
Okay, there are multiple problems with your code.
You make no effort to ensure you don't blow past the size of your
static array.
You skip a spot in the array when appending your manually-added
value
Your array length is wrong
You aren't initializing your variables
Let's start with the last one. Please do something like this:
int i{0}, p, array_length;
This ensures the i variable is properly initialized to zero.
Next, your code does this:
array3[i++] = current_number;
This means that at any given time, i is the length of the array.
But later you do this:
array_length = i;
array3[array_length+1]=p;
Frankly, I would drop variable i entirely and use array_length instead. There is no need for both.
But even without that, you're setting array_length correctly, but then you're inserting to a point AFTER that, so you might start with:
[ 1, 2, 3, 4, 5 ]
At this point, i == 5. Input a 6 and have:
[ 1, 2, 3, 4, 5, 0, 6 ]
Because you put it at index i+1 not at index i.
At this point, array_length is no longer an accurate length. But you do this:
int pos=Heapify_up(array3, array_length+1);
So it kind of works.
I don't know why Heapify_up is returning j -- it's just the midpoint of the array. That's not a useful value.
Furthermore, I don't really know what your heapify thing is trying to accomplish.. It certainly isn't a heap-sort. If the middle and end numbers are in sorted order, it doesn't actually do a thing.
This URL might help you with some code:
Heap sort at Geeks for Geeks
As for using a fix-length array -- that's problematic, too, but using std::vector is probably a bit much for you. I'd make sure that your input loop doesn't run into issues or start with a much longer beginning array.

C++ vector memory access issue

I have a vector with a list of commands as shown below:
//COMMAND INITIALISATION
std::vector<std::string> objectInitialisationAction;
objectInitialisationAction.push_back("CREATE"); //0
objectInitialisationAction.push_back("END_CREATE"); //1
objectInitialisationAction.push_back("START_TIMELINE"); //2
I only access this vector by using my function shown below:
int SearchFor(std::string search, std::vector<std::string> from)
{
int result=-1;
for(int i=0; i<from.size(); i++)
if(from[i]==search)
{
result=i;
break;
}
if(result == -1)
{
std::ofstream error("searching.txt");
error<<"search failed, original value = \""<<search<<"\""<<std::endl;
error<<"values in the table:"<<std::endl;
for(int i=0; i<from.size();i++)
error<<"value "<<i<<": "<<from[i]<<std::endl;
error.close();
}
return result;
}
With only one function call:
commandNum=SearchFor(command[0], objectInitialisationAction);
This is the only place where I access the vector, yet when I call the function for the nth time (it always brakes at the same point in the code) it accesses wrong and outputs gibberish. Some of the code I list below:
search failed, original value = "CREATE"
values in the table:
value 0: CREATE Øç¼ Œ Ôç¼ Œ Ðç¼ Exit ¼ç¼ ¸ç¼ Œ  p«üxðù ; ´ç¼ Œ pëù#òø €< °ç¼ ŒBerlin Sans FB Demi e ¬ç¼ ˆ°¿^nmra œç¼ ŒBerlin Sans FB Demi e ˜ç¼ help ”ç¼ ˆ  object_dump ç¼ test Œç¼ Ž spawn ˆç¼ ‹ load_map „ç¼ Ž
//and so on...
Any suggestions as to why a vector may corrupt like that?
It seems all correct. Compile and execute this. If it is all correct probably the problem is in another part of your code.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int SearchFor(std::string search, std::vector<std::string> from)
{
int result=-1;
for(unsigned int i=0; i<from.size(); i++)
if(from[i]==search)
{
result=i;
break;
}
if(result == -1)
{
std::ofstream error("searching.txt");
error<<"search failed, original value = \""<<search<<"\""<<std::endl;
error<<"values in the table:"<<std::endl;
for(unsigned int i=0; i<from.size(); i++)
error<<"value "<<i<<": "<<from[i]<<std::endl;
error.close();
}
return result;
}
int main()
{
std::vector<std::string> objectInitialisationAction;
objectInitialisationAction.push_back("CREATE"); //0
objectInitialisationAction.push_back("END_CREATE"); //1
objectInitialisationAction.push_back("START_TIMELINE"); //2
for(unsigned int i=0; i<objectInitialisationAction.size(); i++)
{
cout<< objectInitialisationAction[i] << endl;
}
cout << "FOUND " << SearchFor("CREATE", objectInitialisationAction);
return 0;
}
I suggest you to add using namespace std; at the beginning of the file, so you have not to add std::blablabla on each declaration...your code will be more readable :) and please....INDENT IT :)
Your code looks correct to me. In this case, there should be another part of your application that corrupts the memory. For example, there could be an out-of-range array access, a dangling pointer or a use-after-delete somewhere. Tools like Valgrind might help you here.
The code looks ok as it is. The most likely scenario for me is that the length field of your strings gets unintentionally overwritten, because the command, i.e. the actual data, is still there. It's just that the string thinks it's longer than that. (Overwriting the characters wouldn't lead to the output you report: The commands would be overwritten, but the string length would still be short.) Overwriting memory typically happens through an array index or pointer which is out of bounds. The data it points to must have the same linkage as the strings (in your example local or global/static).
One strategy for bug searching would be to occasionally print the length of objectInitialisationAction's element strings; if they are too long you know something went wrong.
It may help to comment out code using a kind of binary search strategy (comment out one half -- mocking it's functionality to keep the prog running -- and look whether the error still occurs, then divide the faulty part again etc.).
Note that you pass the vector by value into SearchFor() which is perhaps unintended. The corruption may happen at the caller's or callee's side which should be easy to test.--
Hoped that helped.
try to pass all params through const refs:
int SearchFor(const std::string& search, const std::vector<std::string>& from)
{
...
}

Array setup in constructor means failure later on

I had an issue where my code segfaulted on attempting to use the size() function of a list. On the advice of stackoverflow :-) I constructed a minimum case in which the segfault occurs (on the call inventory.size() below). It is:
#include <list>
class Thing {};
class Player {
private:
int xpCalcArray[99];
std::list<Thing*> inventory;
public:
Player();
int addToInv(Thing& t); // return 1 on success, 0 on failure
};
Player::Player() {
// set up XP calculation array
for (int i=1; i<100; i++) {
if (i<=10) {
xpCalcArray[i] = i*100;
}
if (i>10 && i<=50) {
xpCalcArray[i] = i*1000;
}
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
}
}
int Player::addToInv(Thing& t) {
if (inventory.size() == 52) {
return 0;
} else {
inventory.push_back(&t);
}
return 1;
}
int main(int argc, char *argv[]) {
Thing t;
Player pc;
pc.addToInv(t);
return 1;
}
I notice that when I remove the setting up of the array in the Player cosntructor, it works fine, so this looks to be the problem. What am I doing wrong?
You are accessing your array out of bounds, which results in undefined behaviour. The valid index range for this array
int xpCalcArray[99];
is 0 to 98. You are accessing index 99 here:
if (i>50 && i<=99) {
xpCalcArray[i] = i*5000;
}
Your outer loop should be
for (int i=0; i<99; i++) { ... }
Note I start from 0, although it is an assumption that you actually want to access the first element.
Then your final condition can be simplified to
if (i>50) {
xpCalcArray[i] = i*5000;
}
If you intended to use a size 100 array, then you need
int xpCalcArray[100];
then loop between int i=0; i<100;.
You are accessing outside the bounds of your array. Doing so causes undefined behaviour and so there is no logical explanation for anything that occurs afterwards. The size of your array is 99 and so the last index is 98. Your for loop goes up to 99, however.
Either make your array size 100:
int xpCalcArray[100];
Or change your for condition to i < 99.
You are overwriting your array of 99 ints by attempting to modify the 2nd→100th elements (rather than 1st→99th).
In your case, this happens to overwrite some memory within the std::list<Thing*> (which exists in memory directly after the array — not always, but evidently for you today) and thus, when you try to use the list, all hell breaks loose when its internal member data is no longer what it thought it was.
You xpCalcArray is defined from 0 up to 98 (being 99 elements large).
Your loop goes from 0 up to 99, taking 100 steps.
The last loop cycle, writes xpCalcArray at location 99, which does not exist. This (indirectly) results in your segmentation fault as shown by the answer of Lightness Races in Orbit.
So, increase the size of xpCalcArray by 1:
int xpCalcArray[100];

C++ program to compute lcm of numbers between 1 to 20 (project euler )

as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;