C++ Segmentation fault with vector - c++

In below code, I'm trying to display Daily Report with the total Sale. Output is correct but exit with segmentation fault. How do I solve this pls?
Output is
Date Total Sales
03Nov13 745
13Jan14 538
Segmentation fault (core dumped)
Code:
for (int index=0;index<stockVector.size();index++)
{
if ( stockVector[index].getTransDate() == stockVector[index+1].getTransDate())
{
int totalSum = ((stockVector[index].getQtyPurchase() * stockVector[index].getUnitPrice()) +
(stockVector[index+1].getQtyPurchase() * stockVector[index+1].getUnitPrice()));
cout << stockVector[index].getTransDate() << "\t\t" << totalSum << endl;
}
}
This is my data in text file which has been stored in vector.
ProductID:Description:Price:Qty:Transaction Date
003:Calendar:5:104:03Nov13
079:Revlon Foundation:5:45:03Nov13
005:MacBook Pro:3500:1:10Jan14
010:NesCafe Latte:1:9:1Jan14
095:Lipton Tea:5:95:13Jan14
096:Milk Tea:3:21:13Jan14
066:Samsung Note 3:450:1:23Jan14
088:HP Mouse:23:100:24Jan14

In your loop, you're using an index (index+1 in the condition) that can reference an element beyond the last element of the vector (when index reaches stockVector.size() - 1). Dereferencing a pointer (which stockVector does when its operator[] is called) at a location beyond the end of an array is undefined behaviour, so anything can happen (including getting a correct result and then crashing).
To solve this, simply clamp the loop to stockVector.size() - 1:
for (int index=0;index<stockVector.size() - 1;index++)
{
// ...
You may however have to evaluate whether this solution is adequate for the last element of your vector.

stockVector[index+1]
That will obviously go past the end of the vector when index reaches size() - 1.
If you need to peek at the next element you will need to verify that you don't go past the end of the vector and you will also need to figure out what to do when you reach the last element and/or have an odd number of elements.

Related

Last Element in my Array is a large number that I never inputted

I'm storing the results of a "Dice Roll" in an Array.
Everything seems to be working fine, except the last value of the Array is a ╠ (-858993460)?
I tried troubleshooting and its happening right in the beginning and I don't know why.
const int QDice = 3;
int Domain = 6 * QDice;
int CD[6 * QDice]{};
do
{
cout << "Array CD[" << i << "] = " << CD[i] << "\n";
i++;
} while (i <= Domain);
This yields:
Array CD[1] = 0
...
Array CD[18] = -858993460
Everything is fine accept the last element.
C++ array index starts from 0, so the array CD[] range is from 1 to 17. When the Domain becomes 18, the array is out of bounds. I suggest that you could modify the code to the following code.
do
{
cout << "Array CD[" << i << "] = " << CD[i] << "\n";
i++;
} while (i <= Domain - 1);
As mentioned in the comments and another answer, you're assuming 1-based indexing while c++ arrays use 0-based indexing. This means index 18 is out-of-bounds, i.e., it is past the end of the array. But why that does that negative number show up?
First of all, when an out-of-bounds condition exists, the program exhibits undefined behaviour. That means the program can do literally anything, whether it's what you intended or not. In practice, though, the program will often assume that arrays are large enough for the index being used. So in your case, it will look up the memory where index 18 ought to be (as if the array were large enough for that), and then try to interpret the bytes it finds there as some meaningful value.
Now, as a general rule, memory can have any value at all, unless you set it to something specific. By initializing your array, you set the memory for each array element to a definite value (0). But just past the end of the array is memory that you haven't set, so those bytes could be anything. In your case, they just happen to be set in such a way that they are interpreted as the -858993460, but that could just as well be any other value.

'i' meaning and why is it there?

I'm new here as well to coding. Recently I've been going through Principles and Practice Using C++ and inside his code there is always an i inserted into his examples. Some are inside "vector's subscript" function, or inside "for statements" such as int i. But he didn't even make an int called i, it's just there. Maybe I missed something while reading, I don't know, but I hope someone wouldn't mind giving me a meaning as to why it's inserted in the places it's placed in, or just the meaning of i.
Below I took one of his examples from page 148 to show you
int main()
{
vector<double> temps; //temperatures
double temp = 0;
double sum = 0;
double high_temp = 0;
double low_temp = 0;
while (cin>>temp) // read and put into temps
temps.push_back(temp) ;
for (int i = 0; i<temps.size(); ++i) // these 'i's
{
if(temps[i] > high_temp) high_temp = temps[i]; // and these
if(temps[i] < low_temp) low_temp = temps[i];
sum += temps[i]; // compute sum
}
cout << " High temperature: " << high_temp<< endl; // find high
cout << " Low temperature: " << low_temp << endl; // find low
cout << "Average temperature: " << sum/temps.size() << endl;
}
When you write a software program, each variable that you declare must have a meaning, must represent something.
This is also the case in the book fragment you just read, only that we are talking about arrays. As you know, arrays are a collection of values of the same value type. Because it's a collection, it means there are 1 or more values into that array.
This raises the question: if there are 1 ore more values, how can I acces one specific value of that array? Here is where the i you read comes in.
The variable i has the meaning of the position of the array I am working on right now, where "working on" can mean reading, writing, etc. Because i is a variable, it must have a data type, hence the int i notation.
Using i as a variable in this context is not mandatory, but it's a very common practice. If you have a matrix, for example, you will need two such variables (one for rows and one for columns) which most likely will be i and j.
This also explains why we use i inside a for loop. In English, this means that the loop works with the elements that have the coefficient number from 0 to the array size.
i was declared as an int type in the for loop, but it could also be declared before that loop. Something like:
int i=0;
...
for (i=0; i<...)
i is declared as a variable of type int, here:
for (int i = 0; .......)
{
// 'i' used here
}
// 'i' cannot be used here
That i has a scope only inside that for loop. After the loop terminates, so does the lifetime of that variable i.
i is a part of convention, where it stands for iteration number.
It has been defined in the for loop:
for (int i = 0 ....
Which basically states that you start from iteration number zero. Once you gain some experience, you will see that iterations don't always start from zero, so i may be initialized with a different value (or a different variable name may be used instead of i altogether).
Mathematically, i is often used in context of a list/array: the ith element or summation from i=0 to i=n etc.
i is an integer, used as an indexing variable. You often see it in loops.
First, let's think about a vector and what it looks like. A vector is a variable-length array.
So if we have a vector named myVector with 5 elements, then we have something that looks like
myVector: item1 item2 item3 item4 item5
Now how do we specify individual items? We'll need to index each item. Traditionally (from mathematics), indexing begins at 0. So to index the first element, we do myVector[0]. To index the second element, we do myVector[1], and so on. (The [] is known as the subscript operator. You can also use myVector.at(0), myVector.at(1), but this is less used.)
Now what if we wanted to find the minimum or maximum value in a vector? We'd need to check each item and compare them. So we'll need to iterate (loop) through the entire array.
How do we do this? How do we iterate through each and every item? To loop through each item, we'd need something to specify the items. To loop through every item, we'd need a loop.
The loop in your code does this, iterating from 0 up to the length of the array/vector.
for (int i = 0; i < temps.size(); ++i) // iterate through EVERY element of the vector
{
// access EACH element of using temps[i]
}

Segmentation fault trying to dereference an iterator

I'm trying to find the maximum value of a vector using std::max_element. When I run the program I get a segmentation fault that I believe is to do with std::end going over the end of the vector? I've tried changing it to std::end(tempdata)-1) but to no avail.
auto max = std::max_element(std::begin(tempdata), std::end(tempdata));
std::ofstream maxcurrent("maxcurrent.txt", std::ios::app);
maxcurrent << v << std::setw(15) << *max << std::endl;
Having looked at this answer I don't see why mine isn't working.
It won't work when max is std::end(tempdata) which can occurs if your tempdata is empty.
Iterator to the greatest element in the range [first, last). If several elements in the range are equivalent to the greatest element, returns the iterator to the first such element. Returns last if the range is empty.
source

Offset calculation in 3D array

In the following code,
int arr[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
cout<<arr[0][0][5]<<endl;
cout<<arr[1][3][0]<<endl;
I get output as, 6 and 11.
How is it indexing an element out of its range?
eg- here the sizes are, depth= 3 col=2 row=2 , In thet case arr[0][0][5] means 5th row, which doesnt exist! Can anyone throw light on this.
Technically, you are invoking undefined behaviour.*
But, most likely, what's happening is that the compiler is calculating the address to read as:
(int *)arr + x*(2*2) + y*2 + z
because your 3D array is really stored in memory as a contiguous linear array.
So in your [0][0][5] case, it's simply reading the (0*4+0*2+5)=5th element (zero-based) of that linear array, which is 6.
Similarly for [1][3][0], it's reading the (1*4+3*2+0)=10th element, which is 11.
* This was discussed in a question I asked: One-dimensional access to a multidimensional array: well-defined C?.
Remember the last time you had a C-style string that you forgot to terminate?
char str[] = {'a','b','c'};
cout << str;
Remember how you printed "abc" then any random gubbins in memory after it because the program kept reading past the array?
It'll do that; it'll just keep going and pull out whatever happens to be there, even though doing so is undefined. The compiler simply doesn't need to warn you about this; you are supposed to figure it out for yourself.
In your case, the data for the next row probably happens to be in memory at that spot.
It's like that:
int arr[depth][col][row];
int temp = arr[x][y][z];
then temp = arr[x * (col * row) + y * row + z]

Getting a memory address in my array?

I'm writing a C++ application that has a user enter a 0 (zero) or a one (1) as input, then stores the numbers as an array and sorts them so that the zeros come first and the ones come last.
However, I think I'm getting a memory address in my array that's messing up the sorting operation.
The function that accepts input looks like this:
cout << "Please enter number " << i+1 << ":\n";
cin >> ar[i];
Then there's a function that's called that sorts the input and displays the sorted list:
sort_elements(ar, number);
... and that function looks like this:
void sort_elements(int ar[], long int num_elements) {
int temp_num;
num_elements -= 1; //since the array starts at 0
cout << "num_elements is " << num_elements << "\n";
for (int i=0; i < (num_elements/2); i++ ) {
if (ar[i] > ar[num_elements-i]) {
temp_num = ar[i];
ar[i] = ar[num_elements-i];
ar[num_elements-i] = temp_num;
}
}
cout << "Here's your neatly sorted list of numbers: \n";
for (int j=0; j <= num_elements; j++) {
cout << ar[j] << ", ";
}
cout << "\n";
}
For a five number input, starting with three "1"s, and ending with two "0"s, this results in an output that looks like this:
1, 0, 1, 1, 1892218304,
I'm assuming the 1892218304 is a memory address, that's messing up the input. Though I don't really know.
Can anyone figure out why my sort operation is getting messed up?
Thanks in advance.
Suggestion
Use vector and sort in standard library
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
int main()
{
std::vector<int> v;
for(int i=0; i < 10; i++)
{
v.push_back(i);
}
std::sort(v.begin(), v.end());
return 0;
}
The number you are seeing is not a memory address, but the value of the 4 bytes either immediately before or immediately after your array, interpreted as an int. Your code has an off-by-one error that causes an access to just outside the array. That much I suspect even though I don't have proof.
However, I can't find anything wrong with the code you posted that would cause it to access outside the array bounds.
Are you sure that num_elements has the correct value when this function is called?
Update to address the pastebin code
Things are going wrong already from the start:
int number;
int ar[number]
This is called a variable-length array and it's not legal in C90 or any flavor of C++. That your program compiles is probably "thanks to" a compiler extension... which helpfully raises a bug: the value of number is not initialized before the array is allocated.
You need to do one of the following:
declare ar as an array of constant size (a hard limit on the number of inputs you can accept)
dynamically allocate ar with new[] after number is entered from the user
(by far preferable) use an std::vector instead of an array
It looks to me like you're just getting an uninitialized value in your output.
Under the circumstances, the simplest "sorting" method is probably a counting sort -- i.e., count the number of 0's and the number of 1's the user enters, and then print out the appropriate number of 0's followed by the appropriate number of 1's.
As Tony said, your sorting algorithm is incorrect.
If we assume the following values:
ar[0] = 0
ar[1] = 1
ar[2] = 0
ar[3] = 1
ar[4] = 0
that gives us num_elements equal to 5.
Running this through your function as written, we get the following sorting behavior:
First pass, i = 0
ar[0] > ar[4] -> not true, so no switch
Secon pass, i = 1
ar[1] > ar[3] -> not true, so no switch
There is no third pass, as your for loop condition is met
i = 2
num_elements/2 = 2
2 is not less than 2
So based on your code, you didn't sort anything. This is the first issue.
Your print problem is interesting, based on what you have shown num_elements has been decremented by 1 at the top of your code snippet in your function - therefore the <= condition is correct and you should not be outside the bounds of your 'ar' array. Are you sure this is the exact code, or perhaps you did not copy it properly here and you are actually having a scoping issue?
(EDIT: Although the other answers suggesting using a built in sorting method via vectors, I'd suggest you still work your current implementation out to figure out WHY this is wrong, and what you need to do to fix it. You will not always have an available type that has built in sorting, so understanding the fundamentals is important for any young programmer.)
EDIT2: Based on the link you provided, you aren't properly defining your integer array. You are defining the array based on an uninitialized integer (int ar[number]) when number has not yet been initialized. You then read a value from the standard input to set number, and assume your array has been dynamically adjusted to be of the size read from cin. It does not work this way. Your entire loop is reading/writing outside the bounds of your array which is a big no-no. You want to read the number first, and then define your array based on the size read. - Looks like Jon beat me again.. BAH! :P
The last element being read and printed to the screen has never been written to. I think it's likely your function which accepts input has a fault, like maybe you have a line like you have here
num_elements -= 1; //since the array starts at 0
at the input function so that the first element you write to is at address 1. Then when you're reading them you read from address zero.
I kind of agree with Jim's point: Use the facilities in the C++ standard library to finish your task as much as possible.
Besides, I suggest you go through the algorithm all by yourself, manually, instead of letting the computer run it for you. Ever heard of the "Rubber Duck Debugging Method"? :-) Have a try.