I'm working on binary matrices. Two of my arrays are getting overlapped. (I checked the addresses).This happens only for few sizes of matrices. Hence I get wrong results. I tried using new to allocate arrays, but I get segmentation fault when I do. Is there a way I can avoid overlapping of memory? I'm using g++ compiler.
This is how I declared the arrays
bool A[size0][size0],B[size0][size0],C[size0][size0];
In the next step I initialize all of them. A and B are the operands and C will be holding the result.
I'm using a custom multiplication algorithm in the next stage. Here's a snippet
for(I=0;I<cnm;I++){
bool Tab[m][size];
bool Ctemp[size][size];
int count=0;
for(uint i=0;i<pow(2.0,m*1.0);i++){
for(uint j=0;j<n;j++){
Tab[i][j]=0; //Initialize
if(i==0){
Tab[i][j] = 0;
}
else{
int dec;
//h is calculated here
dec=gray_map[i-1]^gray_map[i]; //gray_map returns gray code
Tab[i][j] = Tab[i-1][j] ^ B[h][j];
}
....
....
}
}
.....
.....
//Rest of the code
As per my observation Tab and C are overlapped. I checked the memory addresses by printing them. They overlap at the sixth iteration of the second level for loop.(n=9, m=3, size=9, cnm=3). I have NOT used C in between, I use it only in the outer loop.
C-Compliers dont let overlap arrays (except you tell them or they are really buggy).
Most times the reason for such errors are wrong pointer arithmetic or wrong array access.
Even when just long 3 secs at your code, I see, that something is wrong with your access:
you declared Tab[m][..] but you got a loop iterating over i from 0 to 2^m (btw using pow for calculating it, is not very good, use instead a left shift (<<)). And then you access Tab[i][...], so most times you access Tab at undeclared indexes.
Related
I'm getting memory limit exceeded error for this code. I can't find the way to resolve it. If I'm taking a long long int it gives the same error.
Why this error happening?
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
int main()
{
///1000000000000 500000000001 getting memory limit exceed for this test case.
ll n,k;
cin>>n>>k;
vector<ll> v;
vector<ll> arrange;
for(ll i=0;i<n;i++)
{
v.push_back(i+1);
}
//Arranging vector like 1,3,5,...2,4,6,....
for(ll i=0;i<v.size();i++)
{
if(v[i]%2!=0)
{
arrange.push_back(v[i]);
}
}
for(ll i=0;i<v.size();i++)
{
if(v[i]%2==0)
{
arrange.push_back(v[i]);
}
}
cout<<arrange[k-1]<<endl; // Found the kth number.
return 0;
}
The provided code solves a coding problem for small values of n and k. However as you noticed it does fail for large values of n. This is because you are trying to allocate a couple of vectors of 1000000000000 elements, which exceeds the amount of memory available in today's computers.
Hence I'd suggest to return to the original problem you're solving, and try an approach that doesn't need to store all the intermediary values in memory. Since the given code works for small values of n and k, you can use the given code to check whether the approach without using vectors works.
I would suggest the following steps to redesign the approach to the coding problem:
Write down the contents of arrange for a small value of n
Write down the matching values of k for each element of arrange
Derive the (mathematical) function that maps k to the matching element in arrange
For this problem this can be done in constant time, so there is no need for loops
Note that this function should work both for even and odd values of k.
Test whether your code works by comparing it with your current results.
I would suggest trying the preceding steps first to come up with your own approach. If you can not find a working solution, please have a look at this approach on Wandbox.
Assume long long int is a 8 byte type. This is a commonly valid assumptions.
For every entry in the array, you are requesting to allocate 8 byte.
If you request to allocate 1000000000000 items, your are requesting to allocate 8 Terabyte of memory.
Moreover you are using two arrays and you are requesting to allocate more than 8 Terabyte.
Just use a lower number of items for your arrays and it will work.
Disclaimer: I have limited knowledge of C++ due to switching from a college where they didn't teach C++ to another where it was the only language that was taught.
I'm trying to implement the box counting method for a randomly generated 2D cluster in a lattice that's 54x54.
One of the requirements is that we use a 1D array to represent the 2D square lattice, so a transformation is required to associate x and y values (columns and lines, respectively) to the actual positions of the array.
The transformation is "i = x + y*N", with N being the length of the side of the square lattice (in this case, it would be 54) and i being the position of the array.
The box-counting method, simply put, involves splitting a grid into large squares that get progressively smaller and counting how many contain the cluster in each instance.
The code works in the way that it should for smaller lattice sizes, at least the ones that I could verify (for obvious reasons, I can't verify even a 10x10 lattice by hand). However, when I run it, the box size goes all the way to 1/37 and gives me a "stack smashing detected" error.
From what I understand, the error may have something to do with array sizes, but I've checked the points where the arrays are accessed and made sure they're within the actual dimensions of the array.
A "for" in the function "boxTransform(int grid[], int NNew, int div)" is responsible for the error in question, but I added other functions that I believe are relevant to it.
The rest of the code is just defining a lattice and isolating the aggregate, which is then passed to boxCounting(int grid[]), and creating a .dat file. Those work fine.
To "fit" the larger array into the smaller one, I divide each coordinate (x, y) by the ratio of squares on the large array to the small array. This is how my teacher explained it, and as mentioned before, works fine for smaller array sizes.
EDIT: Thanks to a comment by VTT, I went back and checked if the array index goes out of bounds with the code itself. It is indeed the case, which is likely the origin of the problem.
EDIT #2: It was indeed the origin of the problem. There was a slight error in the calculations that didn't appear for smaller lattice sizes (or I just missed it).
//grid[] is an array containing the cluster
//that I want to analyze.
void boxCounting(int grid[]) {
//N is a global constant; it's the length of the
//side of the square lattice that's being analyzed.
//NNew is the side of the larger squares. It will
//be increased until it reaches N
for (int NNew = 1; N - NNew > 0; NNew++) {
int div = N/NNew;
boxTransform(grid, NNew, div);
}
}
void boxTransform(int grid[], int NNew, int div) {
int gridNew[NNew*NNew];
//Here the array elements are set to zero, which
//I understand C++ cannot do natively
for (int i = 0; i < NNew*NNew; i++) {
gridNew[i] = 0;
}
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
if (grid[col + row*N] == 1) {
//This is where the error occurs. The idea here is
//that if a square on the initial grid is occupied,
//the corresponding square on the new grid will have
//its value increased by 1, so I can later check
//how many squares on the larger grid are occupied
gridNew[col/div + (row/div)*NNew]++;
}
}
}
int boxes = countBox(gridNew, NNew);
//Creates a .dat file with the relevant values
printResult(boxes, NNew);
}
int countBox(int grid[], int NNew) {
int boxes = 0;
//Any array values that weren't touched remain at zero,
//so I just have to check that it's greater than zero
//to know if the square is occupied or not
for(int i = 0; i < NNew*NNew; i++) {
if(grid[i] > 0) boxes++;
}
return boxes;
}
Unfortunately this is not enough information to find the exact problem for you but I will try to help.
There are like multiple reasons that you should use a dynamic array instead of the fixed size arrays that you are using except if it's required in your exercise.
If you've been learning other languages you might think that fixed array is good enough, but it's far more dangerous in C++ than in most of the languages.
int gridNew[NNew*NNew]; You should know that this is not valid according to C++ standard, only the GCC compiler made it work. In C++ you always have to know the size of the fixed arrays in compile time. Which means you can't use variables to declare an array.
You keep updating global variables to track the size of the array which makes your code super hard to read. You are probably doing this because you know that you are not able to query the size of the array once you pass it to a function.
For both of these problems a dynamic array is the perfect solution. The standard dynamic array implementation in C++ is the std::vector: https://en.cppreference.com/w/cpp/container/vector
When you create a vector you can define it's size and also you can query the length of the vector with the size() member function.
Even better: You can use the at() function instead of the square brackets([]) to get and element with an index which does bounds check for you and throws an exception if you provided an index which is out of bounds which helps a lot to locate these kind of errors. Because in C++ if you just simply provide an index which does not exist in an array it is an undefined behaviour which might be your problem.
I wouldn't like to write any more features of the vector because it's really easy to find examples on how to do these things, I just wanted to help you where to start.
VTT was right in his comment. There was a small issue with the transformation to fit the large array into the smaller one that made the index go out of bounds. I only checked this on pen and paper when I should've put it in the actual code, which is why I didn't notice it. Since he didn't post it as an answer, I'm doing so on his behalf.
The int gridNew[NNew*NNew]; bit was kind of a red herring, but I appreciate the lesson and will take that into account when coding in C++ in the future.
I am trying to solve Leetcode problem 746 which is a basic Dynamic programming problem. Even though my logic is little complex, it should work perfectly fine. I have had 2 sleepless nights trying to find what the problem in my code is. Can someone point exactly where am I doing heap overflow and how to avoid it ?
Also, I forgot to add, the size of cost is always greater than 3.
I have already tried inserting comments into my solution. I have realized that the problem lies with the costing[1] updating code but what the problem is, I have no idea.
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
if(cost.size() < 3)
return 0;
int costing[2];
costing[0]=cost[0];
costing[1]=cost[1];
int i=1;
while(i<cost.size()-2)
{
if(costing[0]+cost[i]>costing[0]+cost[i+1])
{
costing[0]=costing[0]+cost[i+1];
i++;
}
else if (costing[0]+cost[i]<=costing[0]+cost[i+1])
{
costing[0]=costing[0]+cost[i];
i+=2;
}
if(costing[1]+cost[i+1]>=costing[1]+cost[i+2])
{
cout<<costing[1]+cost[i+1]<<"is greater than " <<costing[1]+cost[i+2]<<"\n";
costing[1]+=cost[i+2];
i+=2;
}
else if (costing[1]+cost[i+1]<costing[1]+cost[i+2])
{
cout<<costing[1]+cost[i+1]<<"is less than " <<costing[1]+cost[i+2]<<"\n";
costing[1]+=cost[i+1];
i++;
}
}
return min(costing[0],costing[1]);
}
};
The initial value of i is 1. It can increment by 4 in one iteration of the while under different conditions (if the first else if and the second if are true).
So in the second iteration of the while, the value of i can become 9.
So in the last else if, cost[i+2] is cost[11]. Since your dataset has only 10 elements (as mentioned in the comment), this results in an out-of-bounds access.
Couldn't it be that your heap has not enough space? Vector allocate continuous memory blocks on the heap. If a vector grows for a long time, the heap may get fragmented. So at some point there is no free block available.
Maybe using std::vector::reserve can help you prevent this behaviour.
Also keep in mind that the indexed access ([i]) to vectors doesn't include range checking as opposed to the at function.
I am trying to create a circular reference to array. For example,
float arr1[10] = {0,1,2,3,4,5,6,7,8,9};
Then I use a variable in loop to access elements of array.
for (int i=0;i<10;i++){
std::cout<<arr1[i]<<std::endl;
//other processing using arr1[i] indexing
}
Here, I can only use i<=10. If I want to make i<=16 and if i>10 then index should go to arr1[0] and proceed from there. What are preferable or recommended ways to do this?
You need to use the modulo operator %.
14 % 10 = 4 So just do this with the index you use to access it.
You should use like #Jdman1699 said the modulo operator. Here you find an example:
int position; //the position you want to get
float out = arr1[position%10];
For your specific program, I would simply suggest putting your base for loop inside of another for loop (as it seems that you want to print out all elements of the array many times over, considering your source code). This is because accessing element n is no different than accessing element n + 10. However, if you are planning to create some sort of function to access any element of the array, I would use the modulo operator-base 10. Maybe,
unsigned long int newidx = iptidx%10;
and then work with newidx.
May be u r looking for...
for (int i=0;i<10;i++){
std::cout<<arr1[i%10]<<std::endl;
//other processing using arr1[i] indexing
}
I am trying to write a function in C++ using MPFR to calculate multiple values. I am currently using an mpfr array to store those values. It is unknown how many values need to be calculated and stored each time. Here is the function:
void Calculator(mpfr_t x, int v, mpfr_t *Values, int numOfTerms, int mpfr_bits) {
for (int i = 0; i < numOfTerms; i++) {
mpfr_init2(Values[i], mpfr_bits);
mpfr_set(Values[i], x, GMP_RNDN);
mpfr_div_si(Values[i], Values[i], pow(-1,i+1)*(i+1)*pow(v,i+1), GMP_RNDN);
}
}
The program itself has a while loop that has a nested for loop that takes these values and does calculations with them. In this way, I don't have to recalculate these values each time within the for loop. When the for loop is finished, I clear the memory with
delete[] Values;
before the the while loops starts again in which case, it redeclares the array with
mpfr_t *Values;
Values = new mpfr_t[numOfTerms];
The number of values that need to be stored are calculated by a different function and is told to the function through the variable numOfTerms. The problem is that for some reason, the array slows down the program tremendously. I am working with very large numbers so the thought is that if I recalculate those values each time, it gets extremely expensive but this method is significantly slower than just recalculating the values in each iteration of the for loop. Is there an alternative method to this?
EDIT** Instead of redeclaring the array over each time, I moved the declaration and the delete[] Values outside of the while loop. Now I am just clearing each element of the array with
for (int i = 0; i < numOfTerms; i++) {
mpfr_clear(Values[i]);
}
inside of the while loop before the while loop starts over. The program has gotten noticeably faster but is still much slower than just calculating each value over.
If I understand correctly, you are doing inside a while loop: mpfr_init2 (at the beginning of the iteration) and mpfr_clear (at the end of the iteration) on numOfTerms MPFR numbers, and the value of numOfTerms depends on the iteration. And this is what takes most of the time.
To avoid these many memory allocations by mpfr_init2 and deallocations by mpfr_clear, I suggest that you declare the array outside the while loop and initially call the mpfr_init2 outside the while loop. The length of the array (i.e. the number of terms) should be what you think is the maximum number of terms. What can happen is that for some iterations, the chosen number of terms was too small. In such a case, you need to increase the length of the array (this will need a reallocation) and call mpfr_init2 on the new elements. This will be the new length of the array for the remaining iterations, until the array needs to be enlarged again. After the while loop, do the mpfr_clear's.
When you need to enlarge the array, have a good strategy to choose the new number of elements. Just taking the needed value of numOfTerms for the current iteration may not be a good one, since it may yield many reallocations. For instance, make sure that you have at least a N% increase. Do some tests to choose the best value for N... See Dynamic array for instance. In particular, you may want to use the C++ implementation of dynamic arrays, as mentioned on this Wikipedia article.