I'm getting free() error while using delete [] operator - c++

I could not figure out why I got
*** Error in `./a.out': free(): invalid next size (fast): 0x00000000006db0e0 ***
while trying to free g, u and subset arrays declared inside subs_sum function in the following code:
#include <iostream>
#include <algorithm>
#include <new>
using namespace std;
int
subs_sum(int n, int * numbers)
{
int * g = new int [n-1];
int * u = new int [n-1];
int * subset = new int [n-1];
int i, j;
int sum = 0, nelem = 0;
int found = 0;
for (i=0; i<=n-1; i++)
{
g[i] = 0;
u[i] = 1;
}
do
{
i = 0;
j = g[0] + u[0];
while ((j>=2) || (j<0))
{
u[i] = -u[i];
i++;
j = g[i] + u[i];
}
if (g[i])
{
g[i] = 0;
nelem--;
sum -= numbers[i];
}
else
{
g[i] = 1;
nelem++;
sum += numbers[i];
}
if (g[n-1]) break;
if (sum == numbers[n-1])
{
if (nelem == n-1) // Success!!!
{
// Print partial result
for (int ll=0; ll<=n-2; ll++)
if (g[ll]) cout << numbers[ll] << "+";
cout << "\b=" << sum << endl;
found = 1;
break;
}
if (n-1-nelem >= 2) // Go deeper.
{
int pp = 0;
for (int ll=0; ll<=n-2; ll++)
if (! g[ll]) subset[pp++] = numbers[ll];
if (subs_sum(n-1-nelem, subset)) // Match found!!!
{
// Print partial result
for (int ll=0; ll<=n-2; ll++)
if (g[ll]) cout << numbers[ll] << "+";
cout << "\b=" << sum << endl;
found = 1;
break;
}
}
}
}
while(1);
delete [] g;
delete [] u;
delete [] subset;
return found;
}
int
main(void)
{
int * numbers;
int i;
cin >> i;
numbers = new int [i];
for (int j=0; j<i; j++)
cin >> numbers[j];
cout << "Sorted Numbers: ";
sort(numbers, numbers+i);
for (int j=0; j<i; j++)
cout << numbers[j] << " ";
cout << endl;
subs_sum(i, numbers);
delete [] numbers;
return 0;
}
I got no one issue if I comment out
delete [] g;
delete [] u;
delete [] subset;
and program ran as expected:
$ echo -e "11\n1\n41\n10\n24\n5\n12\n6\n14\n9\n35\n7\n" | ./a.out
Sorted Numbers: 1 5 6 7 9 10 12 14 24 35 41
1+5=6
9+12+14=35
7+10+24=41
Any idea? Thanks

you are not making your arrays big enough. Allocate them as new int[n] instead of new int[n-1]

int * g = new int [n-1];
Allocates an array of n-1 int, indices 0 to n-1-1.
Later, you access:
for (i=0; i<=n-1; i++)
{
g[i] = 0;
u[i] = 1;
}
Which is in the last iteration:
g[n-1] = 0;
Buffer overrun is a common case of undefined behavior, which means anything may happen.
Seems in this case you scrambled the bookkeeping of your allocator, which was actually diagnosed.
Such a happy outcome cannot be guaranteed.
Why does it say free found the error, and not delete?
Well, the delete-expression under the covers calls the dtor on the object (unless trivial aka no-op as for primitive types) and then the function operator delete.
The latter commonly just forwards the request to free.

Related

Program is meant to count how many duplicates are in an array. However, it returns the wrong frequency values

Normally I would use other methods to fix this program but I am not allowed to use advanced techniques for this project, and so what I have is more or less as far as I'm allowed to go.
So my program is meant to take in an array with 10 numbers and then output how many of each value is in the array. For example, {1, 1, 1, 1, 1, 2, 2, 2, 2, 2} is meant to return
5 1
5 2
However, it returns
6 1
4 2
I've made sure that the finalData and Data arrays are holding the proper values.
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
seems to be outputting the wrong value.
for some reason. I believe the error is in my last function, getResults, more specifically the last for loop. Here is that function.
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
This is my complete code.
#include<iostream>
#include<iomanip>
#include<string>
#include<cmath>
#include <algorithm>
using namespace std;
void printHeader();
int getData(string);
void getResults(int finalData[], int data[]);
const int MAX_VALUE = 10;
int main(void)
{
int countValue = 0;
int freq = 0;
printHeader();
int data[MAX_VALUE] = {};
int frequency[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
cout << "Please enter data position " << i + 1 << "\n";
data[i] = getData("\nPlease enter a valid integer.\n");
}
sort(data, data + MAX_VALUE);
int values[MAX_VALUE] = {};
int secondData[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
secondData[i] = data[i];
}
getResults(data, secondData);
return 0;
}
void printHeader()
{
}
int getData(string error)
{
int userInput = 0;
do
{
cin >> userInput;
if (cin.fail())
{
cout << error;
}
} while (cin.fail());
return userInput;
}
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
Got the right answer. Made the changes I listed at the top as well as the following change to the count function.
cout << count(data, data + MAX_VALUE, finalData[i]) << " " << finalData[i] << "\n";
You have done a simple error. When you call getResults you pass the same array(pointer) to 2 different parameters. Now when you update finalData the unwanted side effect update also data(they are the same pointer(with different name). So when you call count will not return the expected result.
To solve this problem you can do a copy of the input array and give it as second parameter of getResults(...) function.

Largest and second largest number in array C++

I have written a code in C++ for finding largest and second largest element in a array. Code works fine but the problem is location of second largest number is not updated. Although value of second largest number is correct but its location is not correct.
#include<iostream>
using namespace std;
void main()
{
int DATA[10];
int largestNumber, secondLargestNumber, loc1, loc2;
cout << "Enter 10 numbers of array DATA" << endl;
for (int i = 0; i < 10; i++)
{
cin >> DATA[i];
}
largestNumber = DATA[1];
secondLargestNumber = DATA[2];
loc1 = 1;
loc2 = 2;
if (largestNumber < secondLargestNumber)
{
largestNumber = DATA[2];
secondLargestNumber = DATA[1];
}
for (int i = 2; i < 10; i++)
{
if (DATA[i]>largestNumber)
{
secondLargestNumber = largestNumber;
largestNumber = DATA[i];
loc1 = i;
}
else if (DATA[i]>secondLargestNumber)
{
secondLargestNumber = DATA[i];
loc2 = i;
}
}
cout << "Largest Number with location :"<<largestNumber<<" "<<loc1 << endl;
cout << "Second Largest Number location :" << secondLargestNumber<<" "<<loc2 << endl;
cin.get();
cin.get();
}
may I suggest a simpler solution?
#include <functional>
#include <set>
#include <iostream>
int main() {
std::set<int, std::greater<int>> s;
int input;
while(true) { // choose your stopping condition
cin >> input;
s.insert(input);
}
std::cout << (*s.begin()) << (*std::next(s.begin())) << std::endl;
}
if you only keep positions, not values, your code can be significantly simplified:
int largest = 0, second = -1;
for (int i = 1; i < 10; i++) {
if( second == -1 || DATA[i] > DATA[second] ) {
second = i;
if( DATA[second] > DATA[largest] )
std::swap( largest, second );
}
}
use "loc2=loc1" statement at first if block I think it will work ,check this code,
for (int i = 2; i < 10; i++)
{
if (DATA[i]>largestNumber)
{
secondLargestNumber = largestNumber;
loc2=loc1;
largestNumber = DATA[i];
loc1 = i;
}
else if (DATA[i]>secondLargestNumber)
{
secondLargestNumber = DATA[i];
loc2 = i;
}
}

Change and return from a function in C++

I have a task to create a program which makes array via user input and then in new function to create another array which only consists of even elements and then the result should be returned via pointer to the newly created array.
Bear in mind that I just started learning C++ so pointers here are not on spot.
#include <iostream>
using namespace std;
int* getEven(int *niz, int *n)
{
int i;
for(i = 0 ; i < *n ; i++)
{
if(niz[i] % 2 == 0)
cout << niz[i];
}
}
int main()
{
int n, i;
int *niz;
cout << "Enter positive and larger number than 50: ";
cin >> n;
if(n <= 50)
cout << n;
else
{
cout << "Error. Number is lower than 50." << endl;
abort;
}
niz = new int[n];
for(i = 0 ; i < n ; i++)
{
cout << "Enter next element:" << endl;
cin >> niz[i];
}
int *a = getEven(niz, n);
cout << endl;
cout << a[0] << endl;
system("pause");
return 0;
}
If you are intending to create a new array which might not contain all the elements from the first one, you need an additional parameter to keep track of the number of elements in the new array. Here is how you do it:
int* getEven(int *inputArray, int inputLength, int *outputLength)
{
int *outputArray = new int[inputLength];
*outputLength = 0;
for(int i = 0; i < inputLength; i++)
{
if(inputArray[i] % 2 == 0)
{
outputArray[*outputLength] = inputArray[i];
outputLength++;
}
}
return outputArray;
}
And here is an example on how to use it in main:
int outLen = 0;
int *a = getEven(niz, n, &outLen);
for(i = 0; i < outLen; i++)
cout << a[i] << endl;
Also, bear in mind that you will need to manually delete the dynamically allocated arrays to prevent memory leaks. This applies to the array created in the main function too. Therefore, you need to do this:
delete []niz;
delete []a;

c++ dynamic array Floating Point exception

For my homework I had to design an arraylist in c++ using only 1d arrays and pointers to make the array dynamic. I have done ample testing and my functions work correctly, but when I use the main that the teacher has provided me I get this floating point error. The point of this homework is to create a class that will work for the teachers main without changing any code in the main
here is the main:
#include "ArrayList.h"
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
ArrayList arr;
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
cout << "Should contain numbers 1..50, is ";
cout << arr.toString() << endl;
for (int i=arr.size()-1;i>=1;i--)
{
arr.erase(arr[i]);
}
cout << "Should contain only 1, is ";
cout << arr.toString() << endl;
arr.erase(arr[0]);
for (int i=1;i<=50;i++)
{
if (i<=2)
arr.push_back(i);
else
{
int j=1;
while ((j<arr.size()) && (i%arr[j]!=0))
j++;
if (j==arr.size())
{
arr.push_back(i);
}
}
}
cout << "Prime numbers between 1 and 50 are: " << arr.toString() << endl;
}
here is my cpp:
#include<iostream>
#include<string>
#include<sstream>
#include "ArrayList.h"
using namespace std;
void ArrayList:: intialArr(int arr[])
{
for(int i = 0; i < length; i++)
{
arr[i] = 0;
}
}
string ArrayList:: toString()
{
std::ostringstream ss;
for(int i = 0; i < capacity; i++)
{
if(arr[i]>0 || arr[i] <0)
{
ss << arr[i] << " ";
}
}
return ss.str();
}
ArrayList::ArrayList()
{
length = 1;
capacity=0;
arr = new int[length];
intialArr(arr);
}
int& ArrayList:: operator[] (unsigned int i)
{
return arr[i];
}
void ArrayList:: push_back(int m)
{
if(capacity>=length)
{
int oldlength = length;
length = length*2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i < oldlength; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
arr[capacity] = m;
capacity++;
}
void ArrayList:: erase(int m)
{
if(capacity == length/2)
{
length = length/2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i<capacity; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
for(int i = 0; i < capacity; i++)
{
if(arr[i]==m)
{
for(int j = i; j<length; j++)
{
arr[j] = arr[j+1];
}
capacity--;
break;
}
}
cout << "length = " << length << " capacity = " << capacity << " capacity/length = " << capacity*2 << endl;
}
from what I have read online floating point exceptions are normally thrown when you try to divide by zero or an infinate value arises but I dont understand how I am getting either of these issues to arise.
My code get through the main where number 1-50 are added and deleted but I get the error once I go into setting up the array to hold prime numbers (after the arr.erase(arr[0]) in the main)
I just set a couple of tags in the main to find what my number look like going into the while ((j<arr.size()) && (i%arr[j]!=0))and i find that my numbers before the crash are
j = 1 and arr[j] = 2
i = 5 and arr.size() = 4

C++ Passing class Object to function

I'm new to C++ programming.
Now I have the state class. I want to create neighboring states with this class, so I add the function getNeighboringStates() to my class. In this function I pass in "neighboring_states" to function set_neighboring_state(), this function change "neighboring_states"'s value.
In this function, I set a for loop to test. It print out "7 1 0 3 6 4 5 2 8", which is the value I want. But In the function getNeighboringStates(), I also set a for loop that has the same mission as in set_neighboring_state(), but the screen display "0 1 4716672 2686652 2686528 0 4716676 4519501 4716676".
I don't know what's wrong with my code. What do I need to do now?
int n; // The number of columns as well as rows of the board
int k; // The kind of heuristic function to use
int tilesCount; // The number of tiles, including the blank one
int statesCount; // The number of states generated
int* m_initTiles;
int* m_goalTiles;
int tmpTile;
const int UP = 0;
const int DOWN = 1;
const int RIGHT = 2;
const int LEFT = 3;
int* direction;
class State {
public:
State(){}
int getBlankTilePosition() {
for (int i = 0; i < n * n; i++) {
if (stateTiles[i] == 0)
return i;
}
}
void set_neighboring_state(State* neighboring_state, int direction) {
int blankPosition = getBlankTilePosition();
int neighbor_tiles[n * n];
for (int i = 0; i < n * n; i++) {
neighbor_tiles[i] = getStateTiles()[i];
}
switch(direction) {
case UP:
if (blankPosition/n < 1) return;
else {
swap(neighbor_tiles[blankPosition], neighbor_tiles[blankPosition - n]);
neighboring_state->set_tiles(neighbor_tiles);
// This for loop print out "7 1 0 3 6 4 5 2 8"
for (int i = 0; i < n * n; i++)
cout << neighboring_state.getStateTiles()[i] << " "; cout << endl;
}
break;
case DOWN:
if (blankPosition/n == n - 1) return;
else {
swap(neighbor_tiles[blankPosition], neighbor_tiles[blankPosition + n]);
neighboring_state->set_tiles(neighbor_tiles);
}
break;
case LEFT:
if (blankPosition % n == 0) return;
else {
swap(neighbor_tiles[blankPosition], neighbor_tiles[blankPosition - 1]);
neighboring_state->set_tiles(neighbor_tiles);
}
break;
default:
if ((blankPosition + 1) % n == 0) return;
else {
swap(neighbor_tiles[blankPosition], neighbor_tiles[blankPosition + 1]);
neighboring_state->set_tiles(neighbor_tiles);
}
break;
}
}
/*
The maximum number of neighboring state that can be created is 4.
This function return the neighboring states of a certain state.
The first state represents for the "left" neighbor, the second,
the third and the fourth represent the "right", "up, and "down"
neighbor, respectively.
*/
State* getNeighboringStates() {
State* neighboring_states;
neighboring_states = new State[4];
for (int i = 0; i < 4; i++)
set_neighboring_state(&neighboring_states[i], direction[i]);
// This print out "0 1 4716672 2686652 2686528 0 4716676 4519501 4716676"
cout << endl;
for (int i = 0; i < n * n; i++)
cout << neighboring_states[0].getStateTiles()[i] << " ";
cout << endl;
return neighboring_states;
}
State(int* pStateTiles) {
stateTiles = pStateTiles;
}
void set_tiles(int* tiles) {
stateTiles = tiles;
}
int* getStateTiles() {
return stateTiles;
}
private:
int* stateTiles;
};
void input(const char* fileName) {
ifstream fin;
fin.open(fileName);
// read n, k from file
fin >> n >> k;
// allocate m_initTiles and m_goalTiles memory
m_initTiles = new int[n * n];
m_goalTiles = new int[n * n];
for (int i = 0; i < n * n; i++)
fin >> m_initTiles[i];
for (int i = 0; i < n * n; i++)
fin >> m_goalTiles[i];
for (int i = 0; i < n * n; i++)
cout << m_initTiles[i] << " ";
cout << endl;
for (int i = 0; i < n * n; i++)
cout << m_goalTiles[i] << " ";
cout << endl;
fin.close();
}
void initDirection() {
direction = new int[4];
direction[0] = UP;
direction[1] = DOWN;
direction[2] = RIGHT;
direction[3] = LEFT;
}
int main() {
input("nPuzzle.inp");
initDirection();
State init_state (m_initTiles);
State goal_state (m_goalTiles);
State* init_neighbor = init_state.getNeighboringStates();
// int* state_tile = init_neighbor[0].getStateTiles();
// for (int i = 0; i < n * n; i++)
// cout << state_tile[i] << " ";
return 0;
}
int blankPosition = getBlankTilePosition();
int neighbor_tiles[n * n];
Remove int neighbor_tiles[n * n]; line from above code segment and make it global available to all function , so declare it as data of a class not for function i.e. add int neighbor_tiles[n * n]; to class as an data type .