segmentation fault when calling a function - c++

Segmentation fault when calling the Update_Multiplier and gdb debugger shows these:
Program received signal SIGSEGV, Segmentation fault.
0x080b74e8 in Update_Multiplier() ()
double upperbound = 116325;
double objective = 1.1707e+07;
int main()
{
Update_Multiplier();
}
void Update_Multiplier()
{
cout << "function 0" << endl;
// Determine subgradient vectors
double gra[1000][1000];
double grb[1000][1000];
double dumX = 0;
double stepsize[1000][1000];
double tuning=2;
double LRADum[1000][1000];
double LRBDum[1000][1000];
cout << "function 1" << endl;
// update subgradient vectors
for (int i=1; i<=noOfNodes; i++)
{
for (int j=1; j<=noOfNodes; j++)
{
if (C[i][j] != 0)
{
dumX=0;
for (int p=1; p<=noOfCommodity; p++)
{
dumX += X[i][j][p];
}
gra[i][j]=dumX-U[i][j]*Y[i][j]-Q[i][j];
grb[i][j]=Q[i][j]-B[i][j]*Y[i][j];
}
}
}
// update stepsize
cout << "function 2" << endl;
for (int i=1; i<=noOfNodes; i++)
{
for (int j=1; j<=noOfNodes; j++)
{
if (C[i][j] != 0)
{
stepsize[i][j]=(tuning*(UpperBound-Objective))/sqrt((gra[i][j]*gra[i][j])*(grb[i][j]*grb[i][j]));
LRADum[i][j]=LRA[i][j]+stepsize[i][j]*gra[i][j];
LRA[i][j]=LRADum[i][j];
LRBDum[i][j]=LRB[i][j]+stepsize[i][j]*grb[i][j];
LRB[i][j]=LRBDum[i][j];
}
}
}
}

I see two suspicious things in your code.
First, you are taking too much stack space (about ~40 MB).
Second, you are starting the index of the array at 1, where it should be 0:
for (int i=1; i<=noOfNodes; i++)
Change it to:
for (int i=0; i<noOfNodes; i++)

At a guess, you have a stack overflow! You cannot reliably create gigantic arrays on the stack. You need to create them dynamically or statically.

Where did you define noOfNodes? What is the initial value of this? Or, do you read this in from the console? If this is uninitialized, it probably has junk data -- which may or may not explain the crash.

You need a stack of at least 40 megabytes to run this function because you're allocating five arrays of one million eight-byte doubles each.
Change the function to allocate the double arrays from the heap using new.

You should really give us the whole code, e.g. noOfNodes is not defined anywhere.
Just a stab in the dark: are you possibly overflowing C since your indices (i and j) go from 1 to noOfNodes?

First, what Neil said is true.
Second, C and C++ arrays start from index zero. If you declare
int a[100]; // 100 elements, from zeroth to ninety-ninth.
Then its elements are a[0], a[1] ... a[99].

I can not see anything wrong with this code as given, BUT: You might have an off-by-one error if noOfNodes is 1000.
Remember that Arrays are 0-indexed so you have to access indexes 0 - 999 instead of 1 - 1000 as you are doing

me too i have this problem and my function returned std::string now i just do reference an dreturn type void like that:
void readOnDicoFile(std::ifstream file/*If you have "using namespace std;" instruction, put ifstream, not std::ifstream (you can put both)*/)
and before:
std::string readOnDicoFile(std::string fileName/*If you have "using namespace std;" instruction, put ifstream, not std::ifstream (you can put both)*/)

Related

Array doesn't print anything on executing code

I was creating a function that takes an integer number, finds the next multiple of 5 after the number and then if the difference between the multiple and the number is less than 3, then it prints out the multiple else the number itself, finally prints out an array of all the numbers.
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
vector<int> gradingStudents(vector<int> grades) {
int size=grades.size();
int c=0;
int d;
vector<int> array;
for(int i=0;i<size;i++){
while(grades[i]>(c*5)){
c++;
}
d=c*5;
if((d-grades[i])<3){
array[i]=d;
}else{
array[i]=grades[i];
}
d=0;
c=0;
}
return array ;
Now I tried running this function, and the compiler gives shows no error in the program in the code, however the code doesn't print anything.
Someone Please help.
First, I have to say that this code is extremely inefficient. Finding the difference between the closest muliplication of 5 and a number can be simply done by:
int difference = (n - (n + 4) / 5 * 5) - n;
Explanation: C++ is rounding down the division, so (n + 4) / 5 is n / 5 rounded up, and hence (n+4)/5*5 is the closest multiplication of 5.
Another thing, you declare an array but never resize it, so its size is 0. You need to resize it either by specifying the size in the constructor or using the std::vector::resize method.
code:
std::vector<int> gradingStudents(std::vector<int> grades) {
std::size_t size = grades.size();
std::vector<int> array(size);
for (int i = 0; i < size; i++) {
int closestMul = (grades[i] + 4) / 5 * 5;
if (closestMul - grades[i] < 3) {
array[i] = closestMul;
}
else {
array[i] = grades[i];
}
}
return array;
}
Proably your code is crashing, which is why it doesn't print anything. And one reason it might be crashing is your vector use is wrong.
It's very common to see beginners write code like this
vector<int> array;
for (int i=0;i<size;i++) {
array[i] = ...;
But your vector has zero size. So array[i] is an error, always.
Two possible solutions
1) Make the vector the correct size to begin with
vector<int> array(size);
for (int i=0;i<size;i++) {
array[i] = ...;
2) Use push_back to add items to the vector, every time you call push_back the vector increases in size by one.
vector<int> array(size);
for (int i=0;i<size;i++) {
array.push_back(...);
And please don't call your vector array, that's just taking the piss.
i feel nothing is wrong with your function but calling of this function is a bit tricky let me give you a quick main to try may be that will help you.
int main() {
vector <int> test ;
test.push_back(1);
test.push_back(2);
gradingStudents(test);
return 0;
}
Try initially the size of the vector is empty i hope you are sending something from the main . Your code is very inefficient whenever you find time must read how to write an efficient code.

c++ runtime error when 2d array assigning another array value

#include<iostream>
#include<string>
#include <cstring>
using namespace std;
bool b[200][200];
int a[46];
int test_cases;
int n;
int m;
int first;
int second;
int main()
{
cin>>test_cases;
while(test_cases--){
cin>>n;
cin>>m;
for (int i=0;i<2*m;i++){
cin>>a[i];
}
for (int j=0;j<m;j++){
first=a[2*j];
second=a[2*j+1];
b[first][second]=true;
}
}
return 0;
}
Hello. Runtime error seems to occur on the last code 'b[first][second]=true;'
I tried couple of changes and i found if i turn 'b[first][second]=true;' into 'b[second][first]=true;' error doesn't occur, which is simply to change the order of indices.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
I can't figure out where the problem is coming from and i need help. Thank you.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
The world is littered with buggy code because people made assumptions like this. The first thing you should do is prove this correct. That's as simple as placing something like:
if (first < 0 || first > 199 || second < 0 || second > 199) {
cerr << "Violation, first = " << first << ", second = " << second << "\n";
exit(1);
}
immediately before your line that sets the b[][] element to true.
As an aside, it would also be prudent to check other array accesses as well. Since we don't have your test data, we have no idea what value will be input for n or m but, since those values can result in undefined behaviour (by accessing beyond array bounds), they should also be scrutinised.
If you wanted to be sure that those didn't cause problems, you could dynamically allocate to the correct size as necessary. For example, once you've gotten m from the user:
int *a = new int[m*2];
// Use it as you wish, elements <0..m*2-1> inclusive.
delete [] a;

C++ program crashes on iterating till the last element of an array

I have the following code:
int main()
{
int a[5];
for (int i = 0; i <= 5; i++) {
cin >> a[i];
}
for (int i = 0; i <= 5; i++) {
cout << a[i] << endl;
}
}
The program is supposed to take 6 integers as input and just print them to the output. It works fine for the first five integers but crashes while printing the sixth. As far as I know, in c++ an array defined "a[5]" should have 6 elements since it starts from 0, right? What's causing the crash?
int a[5];
is an array of 5 integers! The indexing is 0, 1, 2, 3, 4.
The reason for this is how the elements live in memory. The index tells you how many spots to jump from the start of the array. So the first element, you have to jump 0 spaces, because it is at the very front of the array. The second element, you have to jump 1 space. Get it?
array start |data|data|data|data|data|<nothing here!>
offset from start | 0| 1| 2| 3| 4| not allowed!!
So by trying to jump into a position that doesn't actually exist in the array, you cause Undefined Behaviour. This means your program is garbage. There is no guarantee at all what might happen. It might crash, or worse, it might appear to work, because you actually hit some memory that is really being used to store a completely different object. Then you end up with some really crazy behaviour that is hard to debug.
A loop over an array should look like this:
for (size_t i = 0; i < arraySize; ++i) // ...
^ always <, never <=
But it is better to use std::vector, which will grow to the size you need, and manage all the memory for you. Then you can use myVector.at(3); to access the data, and it will throw an exception if you make a mistake like you did above. Or better, use the "range-based for loop", which will pull out all the elements for you:
#include <vector>
#include <iostream>
int main()
{
const std::size_t howMany = 6; // how many ints to read
std::vector<int> data;
while (data.size() < howMany) { // haven't read enough yet
int tmp = 0;
std::cin >> tmp;
if (!std::cin) { // somehow reading went wrong!
return 1; // exit the program with an error code
}
data.push_back(tmp); // store the value we just read
}
for (int i : data) { // go through all the stored ints
std::cout << i << '\n';
}
}
(Also, see here for some common beginner mistakes you are making).

C++ for loop outputs different results with one array than multiple arrays

I can't understand why the outputs are different when I put 1 array into a very simple for loop and when I put two arrays into it.
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
arrR[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrR);
printarr(arrN);
return 0;
}
This outputs arrR as: 0,1,2,3,4,5,6,...,100 which is what I want, but
it outputs arrN as: 100,1,2,3,4,5,6,...,100 which I do not understand.
If I remove arrR from the for loop arrN prints how I want
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrN);
return 0;
}
This outputs arrN as 0,1,2,3,4,5,6,...,100
Interestingly, if I change all the 100's to 10's in the code this problem also goes away even if I keep both arrays in the for loop.
Can anyone help me understand what I'm missing? I'm sure it's simple because I'm pretty new to C++. Thank you!
Note the condition of for is i<=100, equals sign means you will access the array by arrN[100], then get out of the bound. This is undefined behavior, anything is possible. The valid range should be [0, N) (N = 100), i.e. arrN[0], …, arrN[N - 1] (i.e. arrN[99]).
You might want to change all the conditions to i < 100.
Please note that array indexing start from 0 instead of 1 ends at n-1 instead of n. Now in your function runsim() you are accessing the assigning value 100 to arrN[100] and arrR[100] which is not possible leads to undefined behavior.
You should change the for loop condition
for(int i = 0; i < 100; i++) {
// Do something.
}
Please note that accessing element out bound will not produce any error as well. For more detail please refer Accessing an array out of bounds gives no error

finding even numbers in the array issue (C++)

My code is to extract odd number and even number in an 1D array.
#include <iostream>
using namespace std;
int main() {
int a[6] = {1,6,3,8,5,10};
int odd[]={};
int even[]={};
for (int i=0; i < 6; i++) {
cin >> a[i];
}
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 1) {
odd[i] = a[i];
cout << odd[i] << endl;
}
}
cout << " " << endl;
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 0) {
even[i] = a[i];
cout << even[i] << endl;
}
}
return 0;
}
the output is:
1
3
5
2
1
6
It shows that it successfully extract odd numbers but the same method applied to the even number. It comes with an issue while the even number is 4.
Could anyone help me find the cause here? Thanks.
You've got an Undefined Behavior, so result may be any, even random, even formatted hard drive.
int odd[] = {} is the same as int odd[/*count of elements inside {}*/] = {/*nothing*/}, so it's int odd[0];
Result is not defined when you're accessing elements besides the end of array.
You probably have to think about correct odd/even arrays size, or use another auto-sizeable data structure.
First, although not causing a problem, you initialize an array with data and then overwrite it. The code
int a[6] = {1,6,3,8,5,10};
can be replaced with
int a[6];
Also, as stated in the comments,
int odd[]={};
isn't valid. You should either allocate a buffer as big as the main buffer (6 ints) or use a vector (although I personally prefer c-style arrays for small sizes, because they avoid heap allocations and extra complexity). With the full-size buffer technique, you need a value like -1 (assuming you intend to only input positive numbers) to store after the list of values in the arrays to tell your output code to stop reading, or store the sizes somewhere. This is to prevent reading values that haven't been set.
I don't understand your problem when 4 is in the input. Your code looks fine except for your arrays.
You can use std::vector< int > odd; and then call only odd.push_back(elem) whem elem is odd.