allocation error in c++ - c++

I have this following code to sort number which I read from text file. My text file elements must be like this:
3 6
6
5
1
The first number (3) in the first column represents the number of elements that should I sort, the first number in second column represent the max number which I have to send via array which is 6 here.
And the number must be sorted is 6 5 1.
So this is my code but there is error says "invalid allocation size" and how to send max via array.
I need help please.
Here is my code:
// Read and Sort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<fstream>
using namespace std ;
#include<time.h>
#include <string>
int Max ;
int number_of_items;
const int s= 22;
int arr[s];
int n=sizeof(arr)/sizeof(*arr);
class sort{
public:
int read_file()
{
int num = 0;
int x ;
char filename[50];
ifstream numbersfile ;
cout<<"Please enter the file name below"<<endl<<"_______________________________________________"<<endl;
cin.getline(filename,50);
cout<<"_______________________________________________"<<endl;
numbersfile.open(filename);
if(numbersfile.is_open())
{
for(int i =0;i<n;i++){
numbersfile>>arr[i];
Max=arr[0];
number_of_items=arr[1];
}
}
else{
cout<<"Failed To load requierd file"<<endl;
}
int arr2[s];
cout<<"The elements supposed to be sorted are:"<<endl<<endl;
for(int i =2;i<n;i++){
numbersfile>>arr[i];
cout<<arr[i]<<" "<<endl;
}
counting_sort(arr2,n);
return 0 ;}
int counting_sort(int arr[],int size)
{
int n=size;
int max=arr[0];
for (int i=1;i<n;i++) {
if (arr[i]>max) {
max=arr[i];
}
}
int *output_array=new int[n];
for (int i=0;i<n;i++) {
output_array[i]=0;
}
int *count=new int[max+1];
for (int i=0;i<=max+1;i++) {
count[i]=0;
}
for (int i=0;i<n;i++){
count[arr[i]]=count[arr[i]]+1;
}
for (int i=1;i<max+1;i++) {
count[i]=count[i]+count[i-1];
}
for (int i=n-1;i>=1;i--) {
output_array[count[arr[i]]-1]=arr[i];
count[arr[i]]=count[arr[i]]-1;
}
cout<<"The sorted elements are:"<<endl<<endl;
for (int i=0;i<n;i++) {
cout<<output_array[i]<<" ";
}
cout<<"\n-----------------------------------------------"<<endl;
return 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
clock_t t1,t2;
t1=clock();
sort s1;
s1.read_file();
t2 = clock();
float diff = ((float)t2 - (float)t1)/1000 ;
cout <<"The time taken to execute this process is:\n"<< diff<<" Milliseconds." << endl;
return 0;
}

int *count=new int[max+1];
for (int i = 0; i <= max+1;i++) {
count[i]=0;
}
Note that here you goes out of range, because you try to access the last element as count[max+1], because the <= in the conditional test, and this position is not allocated. It should be like this:
int *count=new int[max+1];
for (int i = 0; i < max+1;i++) {
count[i]=0;
}
I suggest to you to carefully check each for, looking if you aren't accessing some position not bounded/allocated. Use printf's or cout's to debug, this is really useful.

Related

How do I use pointers with arrays in c++ and return a pointer value?

I am trying to use pointers whenever possible in the following code and am having difficulty figuring out how, exactly, to institute the pointers and how to return a pointer value at the end of my first function. I have done some research on the subject but none of the methods I found have been helpful so far, so I was hoping you may have some specialized tips.
Note: I am a beginner.
#include <iostream>
using namespace std;
int mode(int *pies[], int size) {
int count = 1;
int max = 0;
int *mode=pies[0];
for (int i=0; i<size-1; i++)
{
if (pies[i] == pies[i+1])
{
count++;
if (count>max)
{
max = count;
mode = pies[i];
}
}
else
count = 1;
}
return *mode;
}
int main() {
int n;
cout<<"Input the number of people: "<<endl;
cin>>n;
int survey[n];
cout << "Enter the amount of pie eaten by each person:" << endl;
for(int i = 0; i < n; i++) {
cout <<"Person "<<(i + 1)<< ": "<<endl;
cin>>survey[i];
}
cout<<"Mode: "<<mode(survey, n)<< endl;
return 0;
}
Here is an attempt to answer.
In your main(), you call the mode() function with mode(survey, n) while int survey[n]; is an array of int, so you may use int mode(int *pies, int size) instead of int mode(int *pies[], int size) (as the array int survey[n] can be implicitly converted into pointer).
However, you need to modify two more things in your function:
int *mode=pies[0]; is wrong as pies[0] is the first element of an array of int, thus is an int, while int* mode is a pointer on an int which is incompatible. mode should be an int to receive pies[0]. The correct code is then int mode = pies[0].
Your function signature is int mode(int *pies, int size), thus, again, you should return an int. You should then just return mode;
These are only hints on how to make the code compile.
Your next step is to formalize what you would like it to do and then modify the code accordingly
NB: The correct practice is to think about what you would like to achieve first and then code afterwards (but let us say that this is for the sake of helping each other)
To get started using pointers, you may look at some simple tutorials at first:
http://www.cplusplus.com/doc/tutorial/arrays/
https://www.programiz.com/c-programming/c-pointers
https://www.programiz.com/c-programming/c-pointers-arrays
https://www.geeksforgeeks.org/pointer-array-array-pointer/
https://www.geeksforgeeks.org/how-to-return-a-pointer-from-a-function-in-c/
https://www.tutorialspoint.com/cprogramming/c_return_pointer_from_functions.htm
Here is the modified code with the stated modifications above (it compiles):
#include <iostream>
using namespace std;
int mode(int *pies, int size) {
int count = 1;
int max = 0;
int mode=pies[0];
for (int i=0; i<size-1; i++)
{
if (pies[i] == pies[i+1])
{
count++;
if (count>max)
{
max = count;
mode = pies[i];
}
}
else
count = 1;
}
return mode;
}
int main() {
int n;
cout<<"Input the number of people: "<<endl;
cin>>n;
int survey[n];
cout << "Enter the amount of pie eaten by each person:" << endl;
for(int i = 0; i < n; i++) {
cout <<"Person "<<(i + 1)<< ": "<<endl;
cin>>survey[i];
}
cout<<"Mode: "<<mode(survey, n)<< endl;
return 0;
}

How do I find the mode of an array by passing the pointer of that array to a function? C++

So I'm totally new to pointers, I apologize for this, I'm supposed to pass an array of pointers and get the mode of that array. After the array passes as a set of pointers, I can't manipulate the array to find the mode, everything I try results in a syntax error.
EDIT: I changed list to an array of pointers and I get a runtime error.
int main()
{
int size=0;
int *list[size];
cout<<"Please enter the size of your array: ";
cin>>size;
cout<<"\nPlease enter the numbers in your list seperated by spaces: ";
for(int i=0;i<size;i++)
{
cin>>*list[i];
}
cout<<endl;
int mode=getMode(list,size);
cout<<"\n"<<mode<<endl;
return 0;
}
int getMode (int* list[], int arraySize)
{
cout<<"The array you entered is listed below\n "<<list[0];
for(int i=0;i<arraySize;i++)
{cout<<setw(3)<<list[i];}
int *number=list[0];
int count1=0;
int count2=0;
int mode=0;
for(int j=1;j<arraySize;j++)
{
for(int i=1;i<arraySize;i++)
{
if(list[i]==number)
{
count1++; //counts the number of instances that the number occurs
}
}
if(count1>count2)
{
mode= *list[j];
count2=count1;
}
count1=0;
}
return mode;
}
When you pass an array to a function, it automatically decays to a pointer, so you don't need to use &list. And in the function, you shouldn't declare it int *list[], it should just be int list[] or int *list.
Also, in the getMode() function, you need to count the matches of list[j]. You're just counting the repetitions of number, which is list[0].
#include <iostream>
#include <iomanip>
using namespace std;
int getMode (int list[], int arraySize)
{
cout<<"The array you entered is listed below\n "<<list[0];
for(int i=0;i<arraySize;i++)
{cout<<setw(3)<<list[i];}
int count1=0;
int count2=0;
int mode=0;
for(int j=0;j<arraySize;j++)
{
for(int i=0;i<arraySize;i++)
{
if(list[i]==list[j])
{
count1++; //counts the number of instances that the number occurs
}
}
if(count1>count2)
{
mode= list[j];
count2=count1;
}
count1=0;
}
return mode;
}
int main()
{
int size;
int *list;
cout<<"Please enter the size of your array: ";
cin>>size;
list=new int[size];
cout<<"\nPlease enter the numbers in your list seperated by spaces: ";
for(int i=0;i<size;i++)
{
cin>>list[i];
}
cout<<endl;
int mode=getMode(list,size);
cout<<"\n"<<mode<<endl;
return 0;
}
DEMO

How to count duplicated numbers in a sorted array

I am trying to finish a problem where I read a file into the program and output a file with the average, min, max, and the count of how many times that number occurred in the program. However, I cannot figure out how to create an array for duplicated number of the "counts".
If the file that I was trying to read in had the values 19 5 26 5 5 19 16 8 1,
I need the outputted file to read 5---3 times; 8---1 time; 16---1 time; 19--2 times; 26--1 times.
I first sorted my array to read 5 5 5 8 16 19 19 26.
Below is my code with explanations of what I was trying to do:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
double averageArray(int a[], int length); // user defined function to get average
int maxval(int a[], int length); //user defined function to get max val
int minval(int a[], int length); //user defined function to get min val
void bsort(int arr[], int length);// udf to sort array from min to max
int countArray(int a[], int length); //attempt to create a function to get the number of occurrences of a number that is duplicated
int main()
{
char infilename[16];
int nums[50];//newly created array to read in the numbers from the file
int length(0);//array has a length defined by "length"
ifstream fin;
ofstream fout;
cout << "Please enter an input file name: ";
cin >> infilename;
cout << endl;
fin.open(infilename);
if (fin.fail())
{
cerr << "The file " << infilename << " can't be open!"<<endl;
return 1;
}
cout<<"The output to the file statistics.txt should be as follows: "<<endl;
fout.open("statistics.txt");
fout<<"N"<<"\t"<<"Count"<<endl;
cout<<"N"<<"\t"<<"Count"<<endl;
while (fin >> nums[length])
length++;
bsort(nums, length);
for (int i=0; i<length; i++) {
if (nums[i]==nums[i-1]) {
continue;
}
cout<<nums[i]<<"\t"<<countArray(nums,length)<<endl;
fout<<nums[i]<<"\t"<<endl;
}
cout << "\nAverage: " << averageArray(nums,length) << endl;
cout << "Max: "<< maxval(nums,length)<<endl;
cout << "Min: "<< minval(nums,length)<<endl;
fin.close();
return 0;
}
double averageArray (int a[], int length)
{
double result(0);
for (int i = 0; i < length ; i++)
result += a[i];
return result/length;
}
int maxval(int a[], int length)
{
int max(0);
for (int i=1; i<length; i++)
{
if (a[i]>max)
max=a[i];
}
return max;
}
int minval(int a[], int length)
{
int min(100);
for (int i=1; i<length; i++)
{
if (a[i]<min)
min=a[i];
}
return min;
}
void bsort(int a[], int length)
{
for (int i=length-1; i>0; i--)
for (int j=0; j<i; j++)
if (a[j]>a[j+1])
{
int temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
int countArray(int a[], int length)
{
int counter(0);
for (int i=0; i<length; i++){
if (a[i]==a[i+1]) //loop through array and if the number after is the same as the previous number, then count one
counter++;
}
return counter;
}
Though it compiles, the count only shows "3"s as shown in the picture below:
.
Before I give you the solution, please take a moment to remember, you are programming in C++, not C. As such, you ought to use vectors, istream iterators and std::sort. You also ought to use std::map, which easily accomplishes this purpose:
template <typename It>
std::map<int, int> count_occurrences(It it, It end)
{
std::map<int, int> output;
while (it != end) output[*it++]++;
return output;
}
How to combine this with your existing code is left as an exercise for the reader. I suggest you ought to read about iterators.
Your function int countArray(int a[], int length) has no input for the actual number. It always counts how often there are the same numbers behind each other in your array. That happens two times for fives and once for 19 => 3 times.
Solution:
int countArray(int a[], int length, int num)
{
int counter(0);
for (int i=0; i<length; i++){
if (a[i]==num) //loop through array and if the number is the one you are looking for
counter++;
}
return counter;
}
and call you function: countArray(nums, length, nums[i]);
void countArray(int a[], int length)
{
int counter(1);
bool flag(false);
//you take (i+1) index, it can go out of range
for (int i = 0; i < length - 1; i++){
if (a[i]==a[i+1]){ //loop through array and if the number after is the same as the previous number, then count one
flag = true;
counter++;
}
else {
if (flag){
cout<<a[i] << counter << endl;
}
flag = false;
counter = 1;
}
}
}
I didn't code on C for a long time, but I hope it'll help.
This procedure will print you the answer, and you have to call it just once.
I suggest to use std::map which is the best solution to solve your problem. I will try to explain easily the differents steps to do this:
I consider your variables initialized, for instance:
int length = 9;
int nums[length] = {19, 5, 26, 5, 5, 19, 16, 8, 1};
Create the std::map<int,int>, where the key (first int) will be your number and the value (second int) the number of occurence of this number store in the key.
std::map<int,int> listNumber;
Fill your map
// For all numbers read in your file
for(int i=0; i<length; ++i)
{
// Get number value
int n = nums[i];
// Find number in map
std::map<int, int>::iterator it = listNumber.find(n);
// Doesn't exists in map, add it with number of occurence set to 1...
if(it == listNumber.end())
{
listNumber.insert(std::pair<int,int>(n,1));
}
// ... otherwise add one to the number of occurence of this number
else
{
it->second = it->second+1;
}
}
Read the map
// Read all numbers and display the number of occurence
std::cout << "N" << "\t" << "Count" << std::endl;
for(std::map<int, int>::iterator it = listNumber.begin(); it!=listNumber.end(); ++it)
{
std::cout << it->first << "\t" << it->second << std::endl;
}

Filling 2-D arrays from user input

I have a bit of a problem, I am writing a program to ask the user to enter numbers for a Sudoku grid, and then store them in a 2-d array. I know how to print out the array to show the Sudoku grid, But I am having trouble getting the array elements set to the numbers that the user enters, can anyone help?
This is all that I have, which I know is not much but I have only ever done this with 1-d arrays before.
Code:
#include <iostream>
using namespace std;
void fillGrid1(int grid1, int sizeOfArray) {
for(int x = 0; x < sizeOfArray; x++) {
grid1[x][9] = x;
}
}
int main()
{
int grid1[9][9];
fillGrid1(grid1, 9);
for(int row = 0; row < 9; row++) {
for(int column = 0; column < 9; column++) {
cout << grid1[row][column] << " ";
}
cout << endl;
}
}
Here you have two functions, one to interactively fill the hole sudoku by getting the user input. The other for printing the sudoku. With the little information you gave it's what I think you seek:
#include <iostream>
#include <stdio.h>
#include<stdlib.h>
using namespace std;
void interactiveSudokuFill(int grid1[9][9]){
for(int y=0;y<9;y++){
for(int x=0;x<9;x++){
string theString;
cout<<"Write the value to prace in Sudoku["<<y<<"]["<<x<<"] :"<<endl;
std::getline(cin,theString);
int nr=atoi(theString.c_str());
grid1[y][x]=nr;
}
}
}
void printSudoku(int grid[9][9]){
for(int y=0;y<9;y++){
for(int x=0;x<9;x++){
cout<<"["<<grid[y][x]<<"]";
}
cout<<endl;
}
}
int main()
{
int grid1[9][9];
interactiveSudokuFill(grid1);
printSudoku(grid1);
}
There are other more safe/elegant ways of doing this(for example user input should have been checked before delievering it to atoi()), but this way is the simpler I can think of.
Firstly, you're taking in an int where you expect an array:
void fillGrid1(int grid1, int sizeOfArray)
// ^^^^^^^^^
This should be something of the form,
void fillGrid1(int grid1[9][9], int sizeOfArray)
Next is that you should use a nested loop to access the elements of the multidimensional array:
void fillGrid1(int grid1[9][9], int sizeOfArray)
{
for (int i = 0; i < sizeOfArray; ++i)
{
for (int k = 0; k < sizeOfArray; ++k)
{
grid1[i][k] = x; // shouldn't x be the number the user entered?
}
}
}
You should also zero-fill your array:
int grid1[9][9] = {0};

2 dimensions array allocation, c++

I would like to have an array int candidates[9][] where the first dimension is known (9) and the second, depends on the execution.
I found that a method to allocate the array was the following:
int *candidates[9]; /* first allocation at declaration */
for(int i=0;i<9;i++) candidates[i] = new int[6]; /* allocation at execution */
but when I use it like that, and I try to access to candidates[i][j], it doesn't work. I initialize candidate[i] with a function fun() that return and int[] of the right size, but the content of candidate[i][j] is wrong.
candidates[0] = fun();
I don't understand where I am wrong... Thank you for your help :-)
Try int *candidates[9] instead of int candidates[9][] and it should work.
Why dont you try vector template class from STL...code is more neater and comprehensive...
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> arrayOfVecs[9];
//use each array to put as many elements you want, each one different
arrayOfVecs[0].push_back(1);
arrayOfVecs[1].push_back(100);
.
.
arrayOfVecs[1].push_back(22);
arrayOfVecs[0].pop_back();
arrayOfVecs[8].push_back(45);
cout<<arrayOfVecs[1][0]<<endl;//prints 100
return 0;
}
WITH ARRAY OF POINTERS
int main()
{
int* arrayOfPtrs[9];
for(int index = 0;index<9;index++)
{
int sizeOfArray = //determine the size of each array
arrayOfPtrs[index] = new int[sizeOfArray];
//initialize all to zero if you want or you can skip this loop
for(int k=0;k<sizeOfArray;k++)
arrayOfPtrs[index][k] = 0;
}
for(int index = 0;index<9;index++)
{
for(int k=0;k<6;k++)
cout<<arrayOfPtrs[index][k]<<endl;
}
return 0;
}
Try int **candidates=0; followed by candidates = new int *[9] ;.
Code:
#include <iostream>
using namespace std;
int main(void)
{
int **candidates=0;//[9]; /* first allocation at declaration */
candidates = new int *[9] ;
for(int i=0;i<9;i++) candidates[i] = new int ; /* allocation at execution */
for( i = 0 ; i < 9 ; i++ )
{
for( int j = 0 ; j < 9 ; j++ )
{
candidates[i][j]=i*j;
cout<<candidates[i][j]<<" ";
}
cout<<"\n";
}
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}