Heap Corruption Detected: after Normal block (#126) - c++

I cannot for the life of me figure out why I am getting this Debug Error:
Heap Corruption Detected: after Normal block (#126) at
0x004cF6c0
CRT detected that the application wrote to memory after end of heap bugger.
I understand that you need to free memory whenever you use new operator,
which I did and I am still getting problems.
for some reason the program doesn't end correctly in the recursive function.
I debugged it and went through each line of code with breakpoints.
At the end of the if statement in countSum it somehow subtracts 1 from i
and then reenters the if block.....which it is not supposed to do.
Why is this occurring?
/*this program calculates the sum of all the numbers in the array*/
#include <iostream>
#include <time.h>
using namespace std;
/*prototype*/
void countSum(int, int, int, int*);
int main(){
bool flag;
int num;
int sum = 0, j=0;
int *array = new int;
do{
system("cls");
cout<<"Enter a number into an array: ";
cin>>array[j];
cout<<"add another?(y/n):";
char choice;
cin>>choice;
choice == 'y' ? flag = true : flag = false;
j++;
}while(flag);
int size = j;
countSum(sum, 0, size, array);
//free memory
delete array;
array = 0;
return 0;
}
void countSum(int sum, int i, int size, int *array){
if (i < size){
system("cls");
cout<<"The sum is :"<<endl;
sum += array[i];
cout<<"...."<<sum;
time_t start_time, stop_time;
time(&start_time);
do
{
time(&stop_time); //pause for 5 seconds
}
while((stop_time - start_time) < 5);
countSum(sum, (i+1) , size, array); //call recursive function
}
}

array holds enough space for a single int:
int *array = new int;
but there is potentially an attempt to insert more than one int which would result in writing to memory that is not available. Either use a std::vector<int> or it must be known beforehand the maximum number of ints that will be entered before array is allocated.
If this is a learning exercise and you do not want to use std::vector<int> you could prompt the user to enter the number of ints they wish to enter:
std::cout << "Enter number of integers to be entered: ";
int size = 0;
std::cin >> size;
if (size > 0)
{
array = new int[size];
}
Then accept size number of ints. Use delete[] when you use new[].

The solution was to set the size new int[size]....although I wish that you didn't have to set a size if it is dynamic.

Related

Variable length array c++ & No operator >> error?

going through a c++ course and was asked to create a simple program to average values in a user array
i figured id go the extra mile and learn to mess with a few additional types.
I searched online for a fix for the non variable arrays in c, and i know this is where shit hits the fan
//manually allocate the space to the array
int** MyArray = new int* [Length_Of_Array]; // i changed it to float to suit my program
For my error's im getting
ERROR IMAGE
Is there a better alternative to this (sticking to arrays as opposed to vectors) ?
MY FULL CODE
#include <iostream>
using namespace std;
//function declare
float Avg(float Array, int Length);
//Variable declare
int Length_Of_Array;
int main()
{
//Declarations
float Result{};
//User defines size of the array
cout << "Please enter the length of your array (Min 5) ";
cin >> Length_Of_Array;
//User Enters x elements into array
cout << "Please enter" << Length_Of_Array << " Digits into the array " << endl;
//manually allocate the space to the array
float** MyArray = new float* [Length_Of_Array];
//Function use
Result = Avg(MyArray, Length_Of_Array);
//Result
cout << "THE AVERAGE OF YOUR ARRAY IS " << Result << endl;
}
float Avg(float** Array, int length) {
int sum{};
//Stores, enters and calculates user enters elements into array
for (int i = 0; i < length; i++) {
cin >> Array[i];
sum += Array[i];
}
return (sum /length);
}
Let's take a look at this function:
float Avg(float** Array, int length) {
int sum{};
//Stores, enters and calculates user enters elements into array
for (int i = 0; i < length; i++) {
cin >> Array[i];
sum += Array[i];
}
return (sum /length);
}
The type of Array is float** so the type of Array[i] is float *. But you can't read a float * from std::cin and you don't need a float** for a 1D-array. (** is usually used for matrices) Since you are required to use arrays, all you have to do is to change float** to float*.
So you get float Avg(float* Array, int length) and float* MyArray = new float[Length_Of_Array];
Some other hints:
Don't forget to update the forward declaration of Avg also ;)
Don't forget to free the allocated memory if you don't need it anymore with delete[] MyArray;
You should initialize a variable with an actual value like int sum = 0; insted of int sum{};. It makes your code better readble und understandable.
The function signature in function definition and declaration doesn't match.
float** Array means array of array or a pointer to array. Besides you have problem with memory leakage.
You can simply use vector instead:
float Avg(std::vector<float>& Array, int length) {
int sum{};
//Stores, enters and calculates user enters elements into array
for (int i = 0; i < length; i++) {
cin >> Array[i];
sum += Array[i];
}
return (sum /length);
}
and:
std::vector<float> MyArray(Length_Of_Array);

How to return the number of values input into an array?

At the moment, I am stumped and cannot progress on this problem. Any help or guidance would be greatly appreciated. The first part is working, however when I try to return the # of user inputs in the second part I get a Segmentation Fault. Below are the descriptions of both parts::
P2.1 Write a program consisting of main and displayArray functions. The main function declares an integer array with 10 elements and at the same time initializes them with up to 10 arbitrary values. The main function then calls displayArray function to display the contents of the array.
P2.2 Expand P2.1 with an additional fillArray function that prompts the user to enter up to 10 (size of the array) integers. Since a statically allocated array is often partially filled with values less than the actual size or storage capacity of the array (10 in our case), so the fillArray function must return a positive integer value representing the actual # of input values entered by the user.
#include <iostream>
using namespace std;
int displayArray(int arr[]);
int fillArray(int newArray[], int &inputs);
const int size = 10;
int main() {
int x, inputs = 0;
int arr[size] = {0,1,2,3,4,5};
int newArray[] = {};
displayArray(arr);
cout << "Enter .5 when finished. ";
fillArray(newArray, inputs);
cout << inputs;
cin >> x;
return 0;
}
int displayArray(int arr[]) {
for (int i = 0; i < size; i++)
cout << arr[i] << " " << endl;
}
int fillArray(int newArray[], int &inputs) {
for(int i = 0; ; i++) {
cout << "Enter an integer: " << endl;
cin >> newArray[i];
if(newArray[i] == .5) {
inputs = i + 1;
return inputs;
break;
}
}
}
You do not reserve memory for your newArray, since int newArray[] = {} will allocate an array of size 0 (actually not even defined as far as I know). So when calling fillArray, you will exceed array bounds.
Write
int newArray[10] = { 0 }
and it should at least work if you do not enter more than 10 values then.
Further, in fillArray, to not run out of bounds, I'd write...
int fillArray(int newArray[], int &inputs) {
for(inputs = 0; inputs < 10 ; inputs++) {
cout << "Enter an integer: " << endl;
cin >> newArray[i];
if(newArray[i] == 0) {
break;
}
}
inputs++;
return inputs;
}
Note further that the newArray[i] == .5 is at least misleading, since newArray is of type int and .5 is a floating point value. It will never evaluate to true, since the integral value newArray[i] will be converted to a float before comparison, and this conversion will never result in 0.5.

How to use if with array elements in c++

I want to receive only positive numbers from the user which are less than or equal to 4
Here is my code:
#include <iostream>
using namespace std;
int main()
{
unsigned int n;
cin>>n;
unsigned int arr[n];
for (int i =0 ;i<n ; i++){
if (arr[i]<=4)
cin>>arr[i];
}
}
What am I doing wrong with my code? It receives numbers which are greater than 4 .
The behaviour of your code is undefined. You are reading elements of the array before writing to them.
And then you don't check the value inputted by the user.
Note also that variable length arrays are not standard C++ (unsigned int arr[n]; declares such an array). Use a std::vector instead?
Really the best way to sort out these problems is to use a good line-by-line debugger.
#include <iostream>
using namespace std;
int main() {
unsigned int input = 0u; // Holds user input
unsigned int nextPos = 0u; // Next free position in our array
unsigned int arraySize = 0u; // The size of the dynamic array
unsigned int* array = nullptr; // Pointer to our dynamic array
// Ask the user for the array size
cout << "Please Enter The Array Length" << endl;
cin >> arraySize;
// using array = int[arraySize] wouldn't work because the compiler won't know what value the number is at compile time.
// instead we use the 'new' keyword to allocate some memory while the program is running
// this is called dynamic allocation
array = new unsigned int[arraySize];
// The reason it's a while loop instead of a for loop is to only insert numbers into the array
// when the pass the rule if input <= 4u (the u part just means it's unsigned)
while(nextPos < arraySize) {
// Here we ask for an input and store it in the same named input variable
cout << "Please Enter A Valid Number" << endl;
cin >> input;
// Does the input pass the check?
if (input <= 4u) {
// If so store it in the current position in the array and increment
// the line below is the same as doing
// array[nextPos] = input;
// nextPos = nextPos + 1u;
array[nextPos++] = input;
} else {
// When the input doesn't meet the rule, complain about an invalid number
cout << input << " is an invalid number" << endl;
}
}
// A rule in C++ is that we need to manually release any memory we allocate using new
// it would be 'delete variable' for objects or 'delete[] variable' for arrays
delete[] array;
}

How does one dynamically resize arrays?

I'm trying to read an unknown number of elements into the array, when my size reaches the current capacity, I call a function to double the size and copy the contents of the old array into a new array. I got my '&' but it seems it's still passing the array by value.
#include <iostream>
#include <fstream>
using namespace std;
void resize(int*&, int&);
int main() {
ifstream in("numbers.input");
int cap = 10;
double avg;
int total = 0;
int size = 0;
int *arr = new int [cap];
int temp;
for(int i =0; i <cap; i++){
in >> temp;
if(size >= cap) {
resize(arr,cap);
}
arr[i]=temp;
total += arr[i];
size++;
}
avg = (double) total/cap;
cout << cap <<endl;
cout << size <<endl;
cout << total <<endl;
cout << avg;
return 0;
}
void resize(int *&arr,int &cap) {
cap*=2;
int* newArr = new int[cap];
for(int i = 0; i < cap; i++){
newArr[i] = arr[i];
}
delete [] arr;
arr = newArr;
}
Everything you try to implement 'by hand' is already in
the standard library. Use std::vector<> which implements
a doubling/reallocation strategy very similar to what you're
proposing.
#include <fstream>
#include <vector>
int main() {
std::ifstream in("numbers.input");
std::vector<int> arr;
int temp;
while (in >> temp) { arr.push_back(temp); }
// process your data ...
}
See http://www.cplusplus.com/reference/vector/vector/
To answer the question more literally: Arrays are always passed
by reference, typically by passing a pointer to the first element.
Your resize function is taking the pointer by reference and will modify the value of the variable it is called with. However you have a number of bugs:
You copy cap items out of the old array, but you have already doubled cap, leading to an out of bound access and a possible crash.
Your resize function never gets called, due to a bug in your input loop. You should step through in a debugger (or at least add some trace cout calls) to work out what is going on. Try to figure this one out, if you can't let me know.
Your average is using cap as the divisor, that is not correct.
Note: You should add in your question that you can't use vector, because that would be the normal way to do this.
Note 2: In your question, you should also say exactly what is going wrong with your program - "seems to be passing the array by value" is a bit vague - why do you think it isn't passing by value?

How to pass arrays in the main func. w/ c++

#include <iostream>
using namespace std;
const int MAX = 1000;
int ArrMix[MAX];
int *ptrArrPos[MAX];
int *ptrArrNeg[MAX];
int PosCounter = 0;
int NegCounter = 0;
int r;
void accept(int ArrMix[MAX])
{
cout<<"Enter the number of elements in your array: ";
cin>>r;
for (int i = 0; i < r; i++)
{
cout<<"Enter value:";
cin>>ArrMix[i];
}
}
void process(int &i)
{
if(ArrMix[i] >= 0)
{
ptrArrPos[PosCounter] = &ArrMix[i];
PosCounter++;
}
else
{
ptrArrNeg[NegCounter] = &ArrMix[i];
NegCounter++;
}
}
void display(int &i)
{
cout<<"Your passed array is: " << endl;
cout<<ArrMix[i] << endl;
cout <<"Total number of positive integers is: "<<PosCounter<<endl;
cout<<"Your positive array is: "<<endl;
for (int i = 0; i < PosCounter; i++)
{
cout << *ptrArrPos[i] << endl;
}
cout<<endl;
cout <<"Total number of Negative integers is: "<<NegCounter<<endl;
cout<<"Your negative array is: "<<endl;
for (int i = 0; i < NegCounter; i++)
{
cout << *ptrArrNeg[i] << endl;
}
}
int main ()
{
int *i;
int a = &i;
accept(&ArrMix[MAX]);
process(a);
display(a);
system("pause>0");
}
The code you see above is a program use to create a user-defined array list of numbers. It should accept numbers from the user, display the passed array, positive numbers array and its negative numbers array. it should evaluate items, meaning separating negatives #s from positive numbers then creating an array for each. next is to use a counter to identify how many positive #s and negative #s are in each array.
I am having problems in passing the array from one function to another using pointers and calling it in the main function. so please help me?
The expression &ArrMix[MAX] returns a pointer to the integer at index MAX in the array. This index is one beyond the array, meaning you pass a pointer to beyond the array to the function which will then happily write to that memory.
Passing an array is as simple as passing any other argument:
accept(ArrMix);
You also have a problem here:
int *i;
int a = &i;
You declare i to be a pointer to an int. Then you use &i which returns the address of the variable i, in other words a pointer to a pointer to an int, and try to assign this double-pointer to a normal int variable.
It seems to me that you might want to return the number of entries is in the array from the access function, and then loop over the entries the user entered in the array and call process for each value. And then in display instead of taking the ArrMix index it should take the size and loop over that to display the ArrMix array.