I have the fallowing code. I read the guide for what a segmentation fault is, but I'm not 100% sure where its actually happening within my code. It works until I start working with the dynamic array (histogram), more specifically at the //set all initial values to be zero. Within that mess after I'm not sure. Thanks!
The instructor asked to "Use a dynamic array to store the histogram.", Which I think is my issue here.
-Solved-
thanks for the help, the error was in how I initialized the array pointer
rather than
const int hSize = 10;
IntArrayPtr histogram;
histogram = new int[hSize];
I used
const int hSize = 10;
int hValues[hSize] = { 0 };
IntArrayPtr histogram;
histogram = hValues;
Which worked as the instructor wanted.
#include <iostream>
#include <vector>
using namespace std;
typedef int* IntArrayPtr;
int main() {
vector<int>grades;
int newGrade;
cout << "Input grades between 0 and 100. Input -1 to calculate histogram: " << endl;
cin >> newGrade;
grades.push_back(newGrade);
while (newGrade > 0) {
cin >> newGrade;
while (newGrade > 100) {
cout << "less than 100 plz: ";
cin >> newGrade;
}
grades.push_back(newGrade);
}
grades.pop_back();
int size = grades.size();
cout << "Calculating histogram with " << size << " grades." << endl;
//Create dynamic array for the histogram of 10 sections.
const int hSize = 10;
IntArrayPtr histogram;
histogram = new int[hSize];
}
//Make the historgram
int stackValue = 0;
for (int j = 0; j < hSize; j++) {
//Loop through the grade vector slots
for (int i = 0; i < size; i++) {
int testValue = grades[i];
//If the grade at the index is between the stack values of the histogram add one to the value of the slot
if (testValue > stackValue && testValue < stackValue + 10) {
histogram[j]++;
}
}
//After looping through the vector jump up to the next histogram slot and corresponding stack value.
stackValue += 10;
}
//Histogram output. Only output the stacks with values
for (int i = 0; i < 10; i++) {
if (histogram[i] != 0) {
cout << "Number of " << (i + 1) * 10 << "'s: " << histogram[i];
}
}
return 0;
}
Working Code:
#include <iostream>
#include <vector>
using namespace std;
typedef int* IntArrayPtr;
int main() {
vector<int>grades;
int newGrade;
cout << "Input grades between 0 and 100. Input -1 to calculate histogram: " << endl;
cin >> newGrade;
grades.push_back(newGrade);
while (newGrade > 0) {
cin >> newGrade;
while (newGrade > 100) {
cout << "less than 100 plz: ";
cin >> newGrade;
}
grades.push_back(newGrade);
}
grades.pop_back();
int size = grades.size();
cout << "Calculating histogram with " << size << " grades." << endl;
//Create dynamic array for the histogram of 10 sections.
const int hSize = 10;
int hValues[hSize] = { 0 };
IntArrayPtr histogram;
histogram = hValues;
//Make the historgram
int stackValue = 0;
for (int j = 0; j < hSize; j++) {
//Loop through the grade vector slots
for (int i = 0; i < size; i++) {
int testValue = grades[i];
//If the grade at the index is between the stack values of the histogram add one to the value of the slot
if (testValue > stackValue && testValue < stackValue + 10) {
histogram[j]++;
}
}
//After looping through the vector jump up to the next histogram slot and corresponding stack value.
stackValue += 10;
}
//Histogram output. Only output the stacks with values
for (int i = 0; i < 10; i++) {
if (histogram[i] != 0) {
cout << "Number of " << (i + 1) * 10 << "'s: " << histogram[i] << endl;
}
}
return 0;
}
histogram is a pointer, not an array.
While
int histogram[hSize] = {0};
would create a zero-initialised array, your
histogram = { 0 };
does not set any elements to zero (it couldn't, because histogram points to one int, not many).
The braces are ignored – a pretty confusing behaviour inherited from C – and it is equivalent to
histogram = 0;
that is,
histogram = nullptr;
You want
int* histogram = new int[hSize]();
The parentheses value-initialises the array, and in turn its elements.
Value-initialising integers sets them to zero.
(By the way: the habit of typedeffing away asterisks causes more problems than it solves. Don't do it.)
Seg faults are problems with accessing regions of memory you don't have access to, so you need to look at your use of pointers. It often means you have a pointer with a bad value that you just dereferenced.
In this case, the problem is this line:
histogram = { 0 };
This is not setting the histogram values to zero as you think: it's resetting the historgram pointer to zero. Then you later dereference that pointer causing your SegFault (note that this line doesn't even compile with clang, so your compiler isn't helping you any on this one).
Changing that line to:
memset(histogram, 0, hSize);
Will sort the problem in this case.
More generally, to diagnose a segfault there are two tricks I use regularly (though avoidance is better than cure):
Run the program under a debugger: the debugger will likely stop the program at the point of the fault and you can see exactly where it failed
Run the program under Valgrind or similar - that will also tell you where the error surfaced but in more complex failures can also tell you where it was caused (often not the same place).
Related
For this homework problem, we need to create a new jagged array with the code provided by our professor, print the array, and calculate the max, min, and sum of the array's contents. We are only allowed to edit the createAndReturnJaggedArray() and printAndThenFindMaxMinSum(int**,int*,int*,int*) functions, as the rest of the code was provided for us so we could check that we get the correct output.
I'm able to get the program to run, however after printing an initial string it terminates the program giving me the error terminate called after throwing an instance of 'std::bad_array_new_length' what(): std::bad_array_new_length. I believe the problem is in my creation of the jagged array and my allocation of memory for the columns part of the array, however I used the notes we were given as reference and have no idea where the problem is coming from. The entire program is provided below. Thanks for any help!
EDIT/NOTE: We haven't learned vectors yet so we're not allowed to use them.
#include <iostream>
#include <climits>
using namespace std;
class JaggedArray {
public:
int numRows;
int *numColumnsInEachRow;
JaggedArray() {
numRows = 11;
numColumnsInEachRow = new int[numRows];
for (int i = 0; i < numRows; i++) {
if (i <= numRows / 2) {
numColumnsInEachRow[i] = i + 1;
} else {
numColumnsInEachRow[i] = numRows - i;
}
}
readComputeWrite();
}
int **createAndReturnJaggedArray() { // COMPLETE THIS FUNCTION
int **A = new int*[numRows];
for(int i=0;i<numRows;i++){ //allocate columns in each row
A[i] = new int[numColumnsInEachRow[i]];
for(int j=0;j<numColumnsInEachRow[i];j++){
if(i <= numRows/2)
A[i][j] = (i + j);
else
A[i][j] = -1 * (i+j);
}
}
return A;
}
void printAndThenFindMinMaxSum(int **A, int *maxPtr, int *minPtr, int *sumPtr) { // COMPLETE THIS FUNCTION
maxPtr = new int[INT_MIN];
minPtr = new int[INT_MAX];
sumPtr = 0;
for(int i=0;i<numRows;i++){
for(int j=0;j<numColumnsInEachRow[i];j++){
//1. print array
if (j == (numColumnsInEachRow[i]-1))
cout << A[i][j] << endl;
else
cout << A[i][j] << " ";
//2. compute max, min, and sum
sumPtr += A[i][j];
if (A[i][j] > *maxPtr)
maxPtr = new int[A[i][j]];
if (A[i][j] < *minPtr)
minPtr = new int[A[i][j]];
}
}
}
void print(int max, int min, int sum) {
cout << endl;
cout << "Max is " << max << "\n";
cout << "Min is " << min << "\n";
cout << "Sum is " << sum << "\n";
}
void readComputeWrite() {
int max, min, sum;
int **A = createAndReturnJaggedArray();
cout << "*** Jagged Array ***" << endl;
printAndThenFindMinMaxSum(A, &max, &min, &sum);
print(max, min, sum);
}
};
int main() {
JaggedArray jaf;
return 0;
}
As #user4581301 hints at, your problem is in printAndThenFindMinMaxSum. Simply changing it to the below solves your problem:
void printAndThenFindMinMaxSum(int **A, int &maxPtr, int &minPtr, int &sumPtr) { // COMPLETE THIS FUNCTION
maxPtr = INT_MIN;
minPtr = INT_MAX;
sumPtr = 0;
.
.
.
sumPtr += A[i][j];
if (A[i][j] > maxPtr)
maxPtr = A[i][j];
if (A[i][j] < minPtr)
minPtr = A[i][j];
}
}
}
We also need to change readComputeWrite to:
void readComputeWrite() {
int max, min, sum;
int **A = createAndReturnJaggedArray();
cout << "*** Jagged Array ***" << endl;
printAndThenFindMinMaxSum(A, max, min, sum);
print(max, min, sum);
}
I would also recommend changing the name minPtr, maxPtr, and sumPtr to something more appropriate, as they aren't pointer at this point and represent primitive values.
You will note, that I changed pointers to references as this is a more natural adaptation for this type of operation. Essentially, passing by reference allow the user to operate on the passed value in a straightforward manner without the tedious task of making sure you dereference things at the appropriate time. It also allows one to operate in a less error prone manner.
Again, as #user4581301 shrewdly points out, the intent of this assignment was probably to deal with pointers. As such, there are a few things that need to be changed if the OP cannot use references. Observe:
void printAndThenFindMinMaxSum(int **A, int *maxPtr, int *minPtr, int *sumPtr) { // COMPLETE THIS FUNCTION
*maxPtr = INT_MIN; // Make sure to deference before assigning
*minPtr = INT_MAX; // Make sure to deference before assigning
*sumPtr = 0; // Make sure to deference before assigning
for(int i=0;i<numRows;i++){
for(int j=0;j<numColumnsInEachRow[i];j++){
//1. print array
if (j == (numColumnsInEachRow[i]-1))
cout << A[i][j] << endl;
else
cout << A[i][j] << " ";
//2. compute max, min, and sum
*sumPtr += A[i][j]; // Make sure to deference before assigning
if (A[i][j] > *maxPtr) // Make sure to deference before comparing
*maxPtr = A[i][j]; // Make sure to deference before assigning
if (A[i][j] < *minPtr) // Make sure to deference before comparing
*minPtr = A[i][j]; // Make sure to deference before assigning
}
}
}
And the readComputeWrite can stay unaltered from the OP's original attempt.
In the OP's code, they are mainly forgetting to deference before assigning/comparing.
I have a program that generates 10 rows and 5 columns and the user inputs data. My question is, how can I find the maximum and lowest values in each row? I have been working on this for a good hour but cannot figure this out. I have attempted to solve this many times; here is my current code.
#include <iostream>
#include <iomanip>
using namespace std;
int returnMax(int[][]);
int main()
{
double sales[10][5];
string name[10];
double highest;
double lowest;
double avg;
// Populating table
for (int row = 0; row < 1; row++)
{
cout << "Enter the salesman's name: " << endl;
cin >> name[row];
cout << "Enter the amount of sales for the five years" << endl;
for (int col = 0; col < 5; col++) {
cin >> sales[row][col];
}
}
cout << returnMax(sales[1][0]) << endl;
return 0;
}
int returnMax(int a[][])
{
int max;
for (int i = 0; i < 1; i++) {
max = a[i][0];
for (int j = 0; j < 5; j++) {
if (a[i][j] > max)
max = a[i][j];
}
}
return max;
}
Your logic here:
cout << returnMax(sales[1][0]) << endl;
is wrong. The sales[1][0] is only a single element of entire sales array. That means,
sales[1][0] = element of 1st row and 0th column in sales array in which you did not have any values initilized. Because you have initilzed only one single row in your entire array as you have the line:
for (int row = 0; row < 1; row++)
Remember in C++ indexing starts from 0 not from 1. That being said, the above result(uninitialized variables) will lead you to have undefined behavior.
Suggestions:
In modern C++ you have better options than using raw arrays. For
example, use of
std::vector<>
or std::array<>
makes your code both simpler and safer. In your case, you can either
have
std::vector<int> sales(50, 0) // one dimentional: with 10 * 5 entries
and manipulate the rows accordingly(see solution-1) or
std::vector<std::vector<int>> sales(10, std::vector<int>(5, 0));
// two dimensional: with 10 rows and 5 columns
and use range-based for loops so that, you never end up with
out of bounds problems(see solution-2).
Regarding finding the min and max of each row entries, you can
simply apply algorithm function called
std::minmax_element
from algorithm header.
Sample solution - 1
A sample solution using one-dimensional vector array would look like this: SEE LIVE
#include <iostream>
#include <vector> // std::vector
#include <algorithm> // std::minmax_element
#include <string>
int main()
{
constexpr std::size_t rawMax = 2;
constexpr std::size_t colMax = 5;
// one dimentional array with size = (rawMax * colMax)
std::vector<int> sales(rawMax * colMax, 0);
std::vector<std::string> name(rawMax);
// Populating table
for (std::size_t row = 0; row < rawMax; ++row)
{
std::cout << "Enter the salesman's name: "; std::cin >> name[row];
std::cout << "Enter the amount of sales for the five years: " ;
for (std::size_t col = 0; col < colMax; ++col)
std::cin >> sales[(row*colMax) + col]; // convert col and raw to 1D index.
}
/// get the begin and end of each row as iterators
auto rowBeginIter = sales.begin();
auto rowEndIter = sales.begin() + colMax - 1;
for (const std::string& str: name)
{
std::cout << "salesman's name: "; std::cout << str;
auto getMinMaxRow = std::minmax_element(rowBeginIter, rowEndIter + 1);
std::cout << " min: " << *getMinMaxRow.first
<< " max: " << *getMinMaxRow .second << std::endl;
rowBeginIter += colMax; // increment both iterator to the next raw
rowEndIter += colMax;
}
return 0;
}
Sample solution - 2
A sample solution using a vector of vectors(2D) would look like this: SEE LIVE
#include <iostream>
#include <vector> // std::vector
#include <algorithm> // std::minmax_element
#include <string>
int main()
{
constexpr std::size_t rawMax = 2; // to test
constexpr std::size_t colMax = 5;
// initilize thw 2D vector of vectors with (rawMax x colMax)
std::vector<std::vector<int>> sales(rawMax, std::vector<int>(colMax, 0));
// initilize with 0's with a size that of maximum number of rows.
std::vector<std::string> name(rawMax, "");
// Populating table
for (std::size_t row = 0; row < rawMax; row++)
{
std::cout << "Enter the salesman's name: "; std::cin >> name[row];
std::cout << "Enter the amount of sales for the five years: " ;
for (std::size_t col = 0; col < colMax; col++) {
std::cin >> sales[row][col];
}
}
/* print max and min of each person
* use range based for loops to loop through them
* (optional: index based loops can also be used like above)
*/
auto nameIter = name.cbegin();
for(const std::vector<int>& each_row: sales)
{
std::cout << "salesman's name: "; std::cout << *nameIter << "\t";
auto getMinMaxRow = std::minmax_element(each_row.cbegin(), each_row.cend());
std::cout << " min: " << *getMinMaxRow.first
<< " max: " << *getMinMaxRow.second << std::endl;
++nameIter; // increment the iterator of name-vector
}
return 0;
}
First of all, prepare your environment this way:
#define NROWS 10 //use a constant for number of rows
#define NCOLUMNS 5 // use a constant for number of columns
typedef int Matrix[NROWS][NCOLUMNS]; // declare the type Matrix which is 2d Array using NROWS and NCOLUMNS as size
int returnMaxForRow(int,Matrix); //If you want to know the max value of a row, you need to pass the row
so in the main you can do:
int main () {
Matrix sales; //You don't need to specify the size, which is done before
string name[10];
double highest;
double lowest;
double avg;
ecc....
Now your function should do this:
int returnMaxForRow (int row, Matrix a) {
int max = a[row][0];
for (int i = 0; i < NCOLUMNS; i++) {
if (a[row][i] > max){
max = a[row][i];
}
}
return max;
}
so you can call it this way:
cout<< returnMaxForRow(0,sales);
cout<< returnMaxForRow(1,sales);
cout<< returnMaxForRow(2,sales);
cout<< returnMaxForRow(3,sales);
Some Advices:
Use constants or variable to set array's index, such as define statement
When you do sales[1][0] you get a single value (row 1, column 0) and not all the row
Use typedef to declare custom array with different dimensions, it is easier to handle them this way
If you want, you can change the function to return all the max of all the rows.
If you want to get the max of the matrix, the approach is similar.
I am new to c++ programming and am taking a computational physics class where we are analyzing the problem of percolation on a square lattice using a single-cluster algorithm. My professor has given us some base code, and asked us to modify it as well as write some additional code and scripts within and without this specific program. I have written the majority of the code and scripts necessary to solve and plot this problem, but I am having an issue with my main data output program, specifically that of an infinite loop when I set an input parameter to any value other than 0.
Three main function comprise this program, namely LATTICE::LATTICE, CLUSTER::grow, and CUSTER::print, and also uses a standard Mersenne Twister header file. The heavily modified, commented, and toyed with c++ program is as follows:
#include <fstream>
#include <iostream>
#include <math.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <cstdlib>
#include "MersenneTwister.h"
using namespace std;
class PARAMS
{
public:
int Nlin; // linear size of lattice
double pr; // probability for a site
double Nclust; // number of clusters in a bin
double Nbin; // number of bins of data to output
int SEED; // seed for mersenne twister
string latt_; // which lattice
PARAMS();//constructor
};
class LATTICE
{
public:
LATTICE(const PARAMS&);//constructor
int Nsite;// number of lattice sites
int Lx,Ly;
vector<vector<int> > nrnbrs;
void print ();
};
class CLUSTER
{
public:
CLUSTER(const PARAMS&, const LATTICE&);//constructor
void grow(const PARAMS&, const LATTICE&, MTRand&);
void meas_clear(const LATTICE&);
void meas(const LATTICE&);
void binwrite(const PARAMS&, const LATTICE&);
//void print(const LATTICE& latt, int index);
void print(const PARAMS& p, const LATTICE& latt);
~CLUSTER();// destructor
//private:
int size;
vector <int> conf;
vector <int> stack;
double pr;
//int stck_pnt,stck_end;
double avg_size;
ofstream dfout;
vector <int> stck_pnt;
vector <int> stck_end;
int z, pnt, prob, val, row, column;
vector< vector< vector <int> > > imax;
};
int main(void)
{
PARAMS p;
LATTICE latt(p);
CLUSTER cluster(p,latt);
MTRand ran(p.SEED);
latt.print();
/*for (int bin=0;bin<p.Nbin;bin++)
{
cluster.meas_clear(latt);
for(int clust=0;clust<p.Nclust;clust++)
{
cluster.grow(p,latt,ran);
cluster.meas(latt);
}
cluster.binwrite(p,latt);
}
*/
cluster.grow(p, latt, ran);
cluster.print(p,latt);
}
PARAMS::PARAMS(){
//initializes commonly used parameters from a file
ifstream pfin;
pfin.open("param.dat");
if (pfin.is_open()) {
pfin >> Nlin;
pfin >> pr;
pfin >> Nclust;
pfin >> Nbin;
pfin >> SEED;
pfin >> latt_;
}
else
{cout << "No input file to read ... exiting!"<<endl;exit(1);}
pfin.close();
// print out all parameters for record
cout << "--- Parameters at input for percolation problem ---"<<endl;
cout <<"Nlin = "<<Nlin<<"; prob. of site = "<<pr<<endl;
cout <<"Number of clusters in a bin = "<<Nclust<<"; Number of bins = "<<Nbin<<endl;
cout <<"RNG will be given SEED of = "<<SEED<<endl;
cout <<"Percolation problem on lattice --> "<<latt_<<endl;
};//constructor
LATTICE::LATTICE (const PARAMS& p)
{
string latt_=p.latt_;
if(p.latt_=="sqlatt_PBC")
{
Lx=p.Nlin;Ly=p.Nlin;
Nsite=Lx*Ly;
int i;
nrnbrs = vector<vector<int> >(Nsite, vector<int>(4));
for (i=0; i<Nsite; i++){
if((i+1) % p.Nlin != 0) nrnbrs[i][0] = i+1;
else nrnbrs[i][0] = i - p.Nlin + 1 ;
if(i + p.Nlin < Nsite ) nrnbrs[i][1] = i+p.Nlin;
else nrnbrs[i][1] = i - (Nsite-p.Nlin);
if(i % p.Nlin > 0) nrnbrs[i][2] = i-1;
else nrnbrs[i][2] = i-1+p.Nlin;
if(i - p.Nlin >= 0) nrnbrs[i][3] = i-p.Nlin;
else nrnbrs[i][3] = i + (Nsite-p.Nlin);
}
}
else if(p.latt_=="sqlatt_OBC")
{
Lx=p.Nlin;Ly=p.Nlin;
Nsite=Lx*Ly;
nrnbrs = vector<vector<int> >(Nsite, vector<int>(0));
for (int i=0; i<Nsite; i++){
if((i+1) % p.Nlin != 0){
nrnbrs[i].push_back(i+1);
}
if(i + p.Nlin < Nsite ){
nrnbrs[i].push_back(i+p.Nlin);
}
if(i % p.Nlin > 0){
nrnbrs[i].push_back(i-1);
}
if(i - p.Nlin >= 0){
nrnbrs[i].push_back(i-p.Nlin);
}
}
}
else
{cout <<"Dont know your option for lattice in param.dat .. exiting"<<endl;exit(1);}
}
void LATTICE::print()
{
//THIS FUNCTIONS MAY BE CALLED DURING DEBUGGING TO MAKE SURE LATTICE HAS BEEN DEFINED CORRECTLY
cout <<"---printing out properties of lattice ---"<<endl;
cout<<"size is "<<Lx<<"x"<<Ly<<endl;
cout <<"neighbors are"<<endl;
for (int site=0;site<Nsite;site++)
{
cout <<site<<" : ";
for (size_t nn=0;nn<nrnbrs.at(site).size();nn++)
cout<<nrnbrs.at(site).at(nn)<<" ";
cout <<endl;
}
cout << endl;
}
CLUSTER::CLUSTER(const PARAMS& p, const LATTICE& latt)
{
conf.resize(latt.Nsite);
stack.resize(latt.Nsite);
pr=p.pr;// store prob in a private member of cluster
dfout.open("data.out");
}
CLUSTER::~CLUSTER()
{
dfout.close();
}
void CLUSTER::grow(const PARAMS& p, const LATTICE& latt, MTRand& ran)
{
conf.resize(latt.Nsite); // Initalize Nsite elements of lattice to 0 in conf
// 0 = Not Asked; 1 = Asked, Joined; 2 = Asked, Refused
for (int i = 0; i < p.Nclust; ++i) { // Iterate for Nclust values
z = ran.randInt(latt.Nsite - 1); // Random integer between 0 and Nsite; Selects first lattice element in the cluster algorithm per Nclus
stck_pnt.resize(0); // Set stck_pnt and stck_end vectors to size 0; Will be filled when iterating through each Nclust
stck_end.resize(0); //-----------------------------------------------------------------------------------------------
//while (conf[z] != 0) { z = ran.randInt(latt.Nsite - 1); } // Iterate through lattice elements until we select one that has not been asked to join
conf[z] = 1; // Set element z in conf to have been asked to join and accepted
stck_pnt.push_back(z); // Add z to both stck_pnt and stck_end
stck_end.push_back(z);
for (int j = 0; j = 3; ++j) { // Add z's nearest neighbors to stck_end; Ignore if already been asked
if (conf[latt.nrnbrs[z][j] == 0]) {
stck_end.push_back(latt.nrnbrs[z][j]);
}
}
pnt = 1; // Initialize pnt for trasnferral of stack_end values to stck_pnt
while (stck_pnt.size() < stck_end.size()) {
stck_pnt.push_back(stck_end[pnt]); // Add pnt element of stck_end to stck_pnt
double prob = ran.rand(); // Get probability value for testing if cluster grows
if (prob <= pr) {
conf[stck_pnt[pnt]] = 1; // Set the current stck_pnt element to joined in conf
for (int j = 0; j = 3; ++j) { // Add z's nearest neighbors to stck_end; Ignore if already been asked
if (find(stck_end.begin(), stck_end.end(), latt.nrnbrs[stck_pnt[pnt]][j]) != stck_end.end()) {
// The given value already exists in stck_end, don't add it again
}
else { // The given value is not contained in stck_end, add it to stck_end
stck_end.push_back(latt.nrnbrs[z][j]);
}
}
}
else {
conf[stck_pnt[pnt]] = 2; // Set the given value to haven been asked and refused in conf
}
++pnt; // Increment pnt; ++p is more efficient then p++ due to lack of copying value
}
}
}
/*
void CLUSTER::print(const LATTICE& latt, int index)
{
stringstream ss;
string file_name;
ss << index << ".clust";
file_name = ss.str();
ofstream clout;
clout.open(file_name.c_str());
clout << "#" << latt.Lx << " x " << latt.Ly << endl;
for (int y = 0; y < latt.Ly; y++)
{
for (int x = 0; x < latt.Lx; x++)
clout << conf[x + y*latt.Lx] << " ";
clout << endl;
}
clout.close();
}
*/
void CLUSTER::print(const PARAMS& p, const LATTICE& latt)
{
//vector< vector< vector<int> > > imax(latt.Lx, vector< vector<int>>(latt.Ly, vector<int>(1)));
// Resize and allocate memeory for imax
//-------------- Row = y-position = i/Lx --------------- Column = x-position = i%Lx ---------------- val = conf[i]
ofstream myFile;
myFile.open("imax.out");
cout << "THe following output was calculated for the input parameters; Recorded to 'imax.out'" << endl;
cout <<"[index]" << "\t" << "[x-position]" << "\t" << "[y-position]" << "\t" << "[conf val]" << endl << endl;
for (int i = 0; i < latt.Nsite; ++i) {
val = conf[i]; // Find color value
row = i / latt.Lx; // Find row number
column = i%latt.Lx; // Find column number
cout << i << "\t" << column << "\t" << row << "\t" << val << endl;
myFile << i << "\t" << column << "\t" << row << "\t" << val << endl;
}
myFile.close();
double size = 0.0; // Initialize size
for (int i = 0; i < latt.Nsite; ++i) {
if (conf[i] == 1) {
size += 1;
}
}
double avg_size = size / p.Nclust; // Find avg_size
}
void CLUSTER::meas(const LATTICE& latt)
{
avg_size+=(double)size;
}
void CLUSTER::meas_clear(const LATTICE& latt)
{
avg_size=0.;
}
void CLUSTER::binwrite(const PARAMS& p, const LATTICE& latt)
{
dfout << avg_size/((double)p.Nclust)<<endl;
}
When I set Nclust=0 in the input file, the code runs as expected and gives the proper output in the file and console. However, when I set Nclust equal to any other value, I get the proper lattice console output but the program hangs for the cluster algorithm. I at first assumed that my computer and algorithm were slow and inefficient and that the program was working in some non-linear time. However, after leaving the program running for around 30 minutes for a 4x4 lattice (only 16 elements in the conf[] vector), no progress had been made and I assumed that the program was stuck in a loop.
After spending several hours going over the CLUSTER::grow() method line-by-line and experimenting with changing various bits of code, I have been unable to resolve where this loop error originates from. I would assume it is somewhere in the while loop that compares the size of stck_pnt and stck_end, but I cannot figure out why or where this is. Any help with this would be very greatly appreciated.
Tl;dr: For Nclust !=0, CLUSTER:grow gets stuck in an infinite loop
You have infinite loop here:
stck_end.push_back(z);
for (int j = 0; j = 3; ++j) { // <======== HERE
and here:
conf[stck_pnt[pnt]] = 1; // Set the current stck_pnt element to joined in conf
for (int j = 0; j = 3; ++j) { // <======== HERE
I have this code, and I've generated an array of random number twice...
Now, I just want to insert these numbers in to the vector upon execution.
I am using Microsoft Visual Studio.
This is my code:
using namespace std;
int main() {
int gRows, gCols;
std::cout << "Enter Rows: " << std::endl;
std::cin >> gRows;
std::cout << "Enter Cols: " << std::endl;
std::cin >> gCols;
std::vector<std::vector<int>> cGrid;
int numOfElem = gRows*gCols;
int* randNum = new int[numOfElem];
for (int x = 0; x < (numOfElem / 2); x++) {
srand((unsigned int)time(0));
const int fNum = rand() % 20 + 1; //generate num between 1 and 100
const int sNum = rand() % 20 + 1;
randNum[x] = fNum;
randNum[x + 2] = sNum;
}
for (int y = 0; y < numOfElem; y++) {
std::cout << randNum[y] <<std::endl;
}
//int i = 0;
for (int nRows = 0; nRows < gRows; nRows++) {// for every row and column
for (int nCols = 0; nCols < gCols; nCols++) {
cGrid[gRows][gCols] = 0;//card at that coordinate will be equal to
std::cout << cGrid[gRows][gCols];
//i = i + 1;
}
std::cout << std::endl;
}}
How do you add element to array/vector upon execution/compilation (c++)?
You cannot add elements to an array. An array never has more nor less elements than it had when it was first created.
You can add elements to a vector "upon compilation" by using a constructor. Techically the elements are still added at runtime, unless the compiler does some optimization.
During execution, you can use std::vector::push_back or one of the other member functions that std::vector has.
As a sidenote: Calling srand before every other call to rand is a great way to make sure that the numbers returned by rand are not at all random. Secondly rand() % 20 + 1 is not "between 1 and 100" as the comment suggests. Thirdly, you pointlessly overwrite elements in the loop. Fourthly, you didn't initialize all of the elements in the array pointed by randNum before using them.
Hi i am trying to create a bubble sort using dynamic arrays, the code seems to work but throws an run time error : HEAP Corruption Detected(since i am deleting dynamic arrays in the ...i donot understand why i am getting such an error). Also, the last two elements in the given array get sorted but i get the address displayed for the last element . As i am trying to learn dynamic arrays on my own.Kindly help me understand the error. Thanks in advance !!!
Array = {125,12,2,36,19}
#include "stdafx.h"
#include <iostream>
using namespace std;
void bubblesort(int* a, int length); // for bubble sort//
int _tmain(int argc, _TCHAR* argv[])
{
int size;
cout << " enter the size of array: " << endl;
cin >> size;
int* a = new int[size];
cout << "enter the elements in an array: " << endl;
for (int i = 0; i < size; i++)
cin >> *(a+i);
bubblesort(a, size);
delete[] a;
a = NULL;
return 0;
}
void bubblesort(int* a, int length)
{
int temp = 0;
for (int i = 0; i < length; i++)
{
if (a[i] > a[i+1])
{
temp = a[i+1];
a[i+1] = a[i];
a[i]= temp;
}
}
for (int i = 0; i < length; i++)
{
cout << " The elements are : " << endl;
cout << a[i] << endl;
}
}
As (it was) mentioned in the comments, you're reading outside the array.
a[i + 1] = a[i]; //When i == length - 1, this is UB
In the last iteration of the for loop, you'll overwrite whatever is after the end of the array. An array a[length] is only valid from 0 through length - 1.
Also, your bubble sort only runs once, while it is supposed to constantly run until all items are sorted.
On a subjective note, *(a+i) is identical to, but less readable than, a[i].