Program does not terminate - c++

In the following code, when run using GNU GCC v8.2.0, code does not terminate:
int main(void)
{
/* code */
int myArray[] = {2, 4};
int otherArray[] = {777, 888};
for(int i = 0; i<4; i++)
{
myArray[i] = 0;
cout << "myArray[" << i << "]=";
cout << myArray[i] << endl;
cout << "add: " << &myArray[i] << endl;
}
for(int i = 0; i<2; i++)
{
cout << "otherArray[" << i << "]=";
cout << otherArray[i] << endl;
cout << "add: " << &otherArray[i] << endl;
}
return 0;
}
output:
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]^C

for(int i = 0; i<4; i++)
Replace the 4 in the 'for loop' by 2 like this:
for(int i = 0; i<2; i++)
Since you're using a static array so it's better to specify the fixed size, but the most important is to be aware when you try to access the array by comparing the index being processed with the size of the array to avoid this behavior.

You are invoking undefined behaviour by writing the indexes 0-3 of the 2 element array myArray.
As this is undefined behaviour there are no guarantees as to what is happening or what will happen if you run the code again in the future. A likely explanation for your observed behaviour is that when you write myArray[2] that is actually overwriting the value of i causing your loop to restart back at 0.
The simple solution is to make myArray larger or change your for loop limit to 2.
To detect this sort of behaviour use std::array instead and call the at function which has bounds checking and will throw an exception when you go outside the bounds of the array. e.g.:
#include <array>
#include <iostream>
int main(void)
{
/* code */
std::array< int, 2 > myArray = { 2, 4 };
std::array< int, 2 > otherArray = { 777, 888 };
for(int i = 0; i<4; i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
for(int i = 0; i<2; i++)
{
std::cout << "otherArray[" << i << "]=";
std::cout << otherArray.at(i) << "\n";
std::cout << "add: " << &otherArray.at(i) << "\n";
}
return 0;
}
std::array also has the bonus of a size() method which can make your code safer too:
for(int i = 0; i<myArray.size(); i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}

Related

Cannot Create a Lazy String and cannot access memory

After getting a segmentation fault error, the debugger gives me an error that says I cannot access memory at address 0x1. It also says cannot create a lazy string with address 0x0, and a non-zero length. Does anyone know how I can fix this?
Thanks!
#include <iostream>
#include <string>
#include "unorderedSet.h"
using namespace std;
int main()
{
int intArr[] = {12,23,4,7,12,9,10,6,23,11};
//Debugger points to here
string strArr[] = {"banana","apple","pear","grape",
"banana","fig","mango","orange","pear","guava"};
unorderedSet<int> intSet(20);
for (int i = 0; i < 10; i++)
{
intSet.insertEnd(intArr[i]);
}
unorderedSet<string> strSet(20);
for (int i = 0; i < 10; i++)
{
strSet.insertEnd(strArr[i]);
}
cout << "\nInteger Set: " << intSet << endl;
cout << "String Set: " << strSet << endl;
intSet.insertAt(5,30);
cout << "\nInsert At non-duplicate\nInteger Set: " << intSet << endl;
intSet.insertAt(5,11);
cout << "Insert At duplicate\nInteger Set: " << intSet << endl;
strSet.replaceAt(1,"pineapple");
cout << "\nReplace At non-duplicate\nString Set: " << strSet << endl;
strSet.replaceAt(3,"pear");
cout << "Replace At Duplicate\nString Set: " << strSet << endl;
int intArr1[] = {7,0,19,56,22,11,23,5};
//Debugger points to here
string strArr1[] = {"red","yellow","grape","banana","mango","orange","guava"};
unorderedSet<int> intSet1(20);
for (int i = 0; i < 8; i++)
{
intSet1.insertEnd(intArr1[i]);
}
unorderedSet<string> strSet1(20);
for (int i = 0; i < 7; i++)
{
strSet1.insertEnd(strArr1[i]);
}

terminate called after throwing an instance of 'std::out_of_range' in C++

I am new to C++ and learning data structures. In the below code I am getting an "out of range warning", and do not understand what I am doing wrong.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers{100,-1,2,4,55,78,3};
int temp {};
int pass {};
pass = numbers.size();
for(int i {0} ;i<pass-1;i++){
for(int j {0} ; j<pass-1-i ; j++){
if(numbers.at(j) > numbers.at(j+1)){
temp = numbers.at(j);
numbers.at(j)=numbers.at(j+1);
numbers.at(j+1)=temp;
}
}
}
cout << numbers.at(0) << endl;
cout << numbers.at(1) << endl;
cout << numbers.at(2) << endl;
cout << numbers.at(3) << endl;
cout << numbers.at(4) << endl;
cout << numbers.at(5) << endl;
cout << numbers.at(6) << endl;
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
return 0;
}
It seems like you may not understand how std::vectors work.
You have only declared 7 elements in your vector which means you can only go up to the index 6. This is because std::vector's indices start at 0. This is true for std::array as well.
vector<int> numbers{100,-1,2,4,55,78,3};
However, in your code you have put these two statements:
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
which doesn't work because like I mentioned you can only go up to index 6.
You should also consider using a for loop like the comments mention above. It is more simple to use and is less work.
For example eith a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers{ 100,-1,2,4,55,78,3 };
int temp{};
int pass{};
pass = numbers.size();
for (int i{ 0 }; i < pass - 1; i++) {
for (int j{ 0 }; j < pass - 1 - i; j++) {
if (numbers.at(j) > numbers.at(j + 1)) {
temp = numbers.at(j);
numbers.at(j) = numbers.at(j + 1);
numbers.at(j + 1) = temp;
}
}
}
std::cout << "v = { ";
for (int i = 0; i < numbers.size(); i++) {
std::cout << numbers.at(i) << ", ";
}
std::cout << "}; \n";
return 0;
}
Output:
v = { -1, 2, 3, 4, 55, 78, 100, };

Write a function that returns a pointer to the maximum value using pointers c++

This is the problem that I'm trying to solve for class in C++.
Write a function that returns a pointer to the maximum value of an array of floating-point data: double* maximum(double* a, int size). If size is 0, return nullptr.
The issues I'm having are that:
The final output is not the correct location for the maximum value in the array.
An error that says: "cannot convert 'double**' to 'double*' in the initialization".
If I use nullptr at any point in this code, CodeBlocks gives me an error.
#include <iostream>
using namespace std;
// return pointer to location from function
double * maximum(double* a, int size)
{
double maxVal = a[0]; // this is the starting max value
double* max_pos = &a; // points to the value in a[0]
// initialis]ze both variables
for(int i = 0; i < size; i++){
if(a[i] > maxVal){
maxVal = a[i];
cout << max_pos << endl;
max_pos = &a[i];
}
}
// return address
return max_pos;
}
int main()
{
double myarr[5];
int i = 0;
int arrSize = 5;
cout << "Input 5 floating point values for your array" << endl;
for(i = 0; i < arrSize; i++){ // loop to input values
cin >> myarr[i];
}
for(int j = 0; j < arrSize; j++){
cout << "Location for " << myarr[j] << " = " << &myarr[j] << endl;
}
double* maxNum = maximum( myarr, arrSize);
cout << &maxNum << endl;
return 0;
}
This is the output I'm getting after finding max_pos:
The code you showed has a few mistakes in it:
using namespace std; is bad!
you are not following your instructions to return nullptr when size is 0.
you are trying to initialize max_pos (a double*) with &a (a double**), which is a compiler error.
you are passing &maxNum (a double**) to std::cout, printing the address of the maxNum variable itself, not the address that it is pointing to (the found array element). You need to pass maxNum (a double*) if you want to print the address of the found element, or pass *maxNum (a double) if you want to print the value of the found element.
Try something more like this instead:
#include <iostream>
// return pointer to location from function
double* maximum(double *a, int size)
{
if (size == 0) return 0;
// initialize both variables
double* max_pos = a; // points to the value in a[0]
double maxVal = *max_pos; // this is the starting max value
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
for(int i = 1; i < size; ++i){
if (a[i] > maxVal){
max_pos = &a[i];
maxVal = *max_pos;
std::cout << "max_pos = " << max_pos << " (" << maxVal << ")" << std::endl;
}
}
// return address
return max_pos;
}
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
for(int i = 0; i < arrSize; ++i) { // loop to input values
std::cin >> myarr[i];
}
for(int j = 0; j < arrSize; ++j) {
std::cout << "Location for " << myarr[j] << " = " << &myarr[j] << std::endl;
}
double* maxNum = maximum(myarr, arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo
And then, you can throw it all away and use STL algorithms instead, like std::max_element():
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
const int arrSize = 5;
double myarr[arrSize];
std::cout << "Input " << arrSize << " floating point values for your array" << std::endl;
// loop to input values
std::copy_n(std::istream_iterator<double>(std::cin), arrSize, myarr);
for(int i = 0; i < arrSize; ++i) {
std::cout << "Location for " << myarr[i] << " = " << &myarr[i] << std::endl;
}
double *maxNum = std::max_element(myarr, myarr + arrSize);
std::cout << "maxNum = " << maxNum << " (" << *maxNum << ")" << std::endl;
return 0;
}
Live Demo

display string sub vector C++

I am new in C++, I created a struct called Device with two fields
string MacAdress
vector<string> RSSI
Then, I created a vector of structure: vector<Device> Devices
I want to extract the vector<string> RSSI and display its contant.
Here is where I got stuck in my main.cpp:
cout << "display MAC and RSSI"<< endl;
Device CurrentDevice;
for(int j=0; j<Devices.size();j++)
{
CurrentDevice = Devices.at(j);
vector<string>::const_iterator begin = CurrentDevice.GetRSSIs().begin();
vector<string>::const_iterator last = CurrentDevice.GetRSSIs().begin() + CurrentDevice.GetRSSIs().size();
vector<string> intermed(begin+1, last);
cout << "Size: "<< intermed.size() << endl;
for (int i = 0 ; i < intermed.size(); i++)
{
cout << intermed[i] << endl;
cout << "device n°"<< j+1<<" " << "MAC "<< " "<< CurrentDevice.GetMacAdress()<< endl;
for(int k=0; k<intermed.size();k++)
{
cout << "device n°" << j;
cout << "\tRSSI " << k << " = " << intermed.at(k)<< endl;
}
}
return 0;
}
I end up with Size=0
here is some simplified code that does not use iterators but should still do the job:
#include <iostream>
#include <string>
#include <vector>
int main()
{
struct Device {
std::string MacAddress;
std::vector<std::string> RSSI;
};
std::vector<Device> Devices;
// add some stuff to first object
Device CurrentDevice1;
CurrentDevice1.MacAddress = "A-B-C";
CurrentDevice1.RSSI.push_back("rssi11");
CurrentDevice1.RSSI.push_back("rssi12");
CurrentDevice1.RSSI.push_back("rssi13");
Devices.push_back(CurrentDevice1);
// add some stuff to second object
Device CurrentDevice2;
CurrentDevice2.MacAddress = "D-E-F";
CurrentDevice2.RSSI.push_back("rssi21");
CurrentDevice2.RSSI.push_back("rssi22");
Devices.push_back(CurrentDevice2);
// see object MAC's
for (int i = 0; i < Devices.size(); i++){
std::cout << "device " << i+1 << " MAC: " << Devices[i].MacAddress << std::endl;
}
// see object RSSI's
for (int j = 0; j < Devices.size(); j++){
for (int k = 0; k < Devices[j].RSSI.size(); k++){
std::cout << "device " << j + 1 << " RSSI: " << k +1 << " : " << Devices[j].RSSI[k] << std::endl;
}
std::cout << "\n";
}
return 0;
}
I'm not sure about what do you want to obtain, but I suppose the problem is in the following lines
vector<string>::const_iterator last = CurrentDevice.GetRSSIs().begin() + CurrentDevice.GetRSSIs().size();
vector<string> intermed(begin+1, last);
Do you want to obtain a copy of CurrentDevice.GetRSSIs()?
In this case, you can use begin() and end()
vector<string> intermed(CurrentDevice().GetRSSIs().begin(),
CurrentDevice().GetRSSIs().end());
or, simpler, invoke the copy constructor,
vector<string> intermed(CurrentDevice().GetRSSIs());

how to use exceptions and pointers in a vector class

I have this vector class, and I was provided with a driver to test the class. Most of it seems to work fine but I think there is something wrong with the exceptions part (which I haven't quite fully understood)
Here is the code for the class .cpp file
int myVector::at(int i)
{
if(i<vsize)
return array[i];
throw 10;
}
and here is the driver code
#include "myVector.h"
#include <iostream>
using namespace std;
int main()
{
// Create a default vector (cap = 2)
myVector sam;
// push some data into sam
cout << "\nPushing three values into sam";
sam.push_back(21);
sam.push_back(31);
sam.push_back(41);
cout << "\nThe values in sam are: ";
// test for out of bounds condition here
for (int i = 0; i < sam.size( ) + 1; i++)
{
try
{
cout << sam.at(i) << " ";
}
catch(int badIndex)
{
cout << "\nOut of bounds at index " << badIndex << endl;
}
}
cout << "\n--------------\n";
// clear sam and display its size and capacity
sam.clear( );
cout << "\nsam has been cleared.";
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
// Push 12 values into the vector - it should grow
cout << "\nPush 12 values into sam.";
for (int i = 0; i < 12; i++)
sam.push_back(i);
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capcacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
cout << "\nTest to see if contents are correct...";
// display the values in the vector
for (int i = 0; i < sam.size( ); i++)
{
cout << sam.at(i) << " ";
}
cout << "\n--------------\n";
cout << "\n\nTest Complete...";
cout << endl;
system("PAUSE");
return 0;
}
Any help is appreciated. Thanks
The driver that you have provided:
try {
cout << sam.at(i) << " ";
}
catch(int badIndex) {
cout << "\nOut of bounds at index " << badIndex << endl;
}
expects that int will be thrown (a bit weird design, but well... this is the code that will use your class...). Your implementation of at() might look like this:
int& myVector::at(int i) throw(int) {
if (i < vsize)
return array[i];
throw i;
}
just try to follow one simple rule: throw by value, catch by reference.
Also note that you have a pointer:
private:
int* array;
which points to dynamically allocated memory allocated in constructor and copy constructor and freed in destructor :
myVector::myVector(int i)
{
...
array = new int[maxsize];
}
myVector::myVector(const myVector& v)//copy constructor
{
...
array =new int[maxsize];
}
myVector::~myVector()
{
delete[] array;
}
But how about the assignment operator ? See What is The Rule of Three?
Your stop condition of for loop ends it one element after the last one (i.e. you cannot access 4th element of sam vector because there are only three elements).
std::vector::at throws std::out_of_range exception in such situation (see: http://en.cppreference.com/w/cpp/container/vector/at), not int one. So you should change your exception handling part to something like this:
#include <exception>
try
{
cout << sam.at(i) << " ";
}
catch(std::out_of_range exc)
{
cout << "\nOut of bounds at index " << exc.what() << endl;
}