Dynamic Memory Allocation and Heap Corruption - c++

For an assignment for school, I need to create a program that takes one array and splices another into it, assigning the first X values of the first array into a new array, then all of the second, and then the rest of the first. It is also required that this is done by means of dynamically allocated arrays. I don't understand why, but for some reason, the heap is becoming corrupted and I can't figure out why. I am just now learning about pointers, so the solutions I have found don't make much sense to me.
If someone could point out exactly what I'm doing wrong, and explain it to me so that I can learn from my mistakes, I'd greatly appreciate it. Thanks!
#include <stdlib.h>
#include <iostream>
#include <time.h>
int* createArray(int);
int* splice(int[], int[], int, int, int);
void arrayPrint(int []);
using namespace std;
int main(void)
{
int firstLength, secondLength, copyLength;
cout << "Enter the length of the first array: ";
cin >> firstLength;
cout << "Enter the length of the second array: ";
cin >> secondLength;
cout << "Enter the length of the first array to be copied: ";
cin >> copyLength;
int* firstArray;
int* secondArray;
int* thirdArray;
srand(100);
firstArray = createArray(firstLength);
secondArray = createArray(secondLength);
firstArray = new int[firstLength];
for (int i = 0; i < firstLength; i++)
firstArray[i] = rand() % 100;
secondArray = new int[secondLength];
for (int i = 0; i < secondLength; i++)
secondArray[i] = rand() % 100;
thirdArray = splice(firstArray, secondArray, firstLength, secondLength, copyLength);
cout << "First Array: " << endl;
for (int i = 0; i < firstLength; i++)
{
cout << firstArray[i] << ", ";
}
arrayPrint(firstArray);
cout << endl << "Second Array: " << endl;
for (int i = 0; i < secondLength; i++)
{
cout << secondArray[i] << ", ";
}
arrayPrint(secondArray);
cout << endl << "Spliced Array: " << endl;
arrayPrint(thirdArray);
delete firstArray;
delete secondArray;
delete thirdArray;
system("pause");
return 0;
}
int* createArray(int arrayLength)
{
int* createdArray;
createdArray = new int[arrayLength];
for (int i = 0; i < arrayLength; i++)
createdArray[i] = rand();
return createdArray;
}
int* splice(int firstArray[], int secondArray[], int firstLength, int secondLength, int copyLength)
{
int* splicedArray;
splicedArray = new int[copyLength];
for (int i = 0; i < copyLength; i++)
{
splicedArray[i] = firstArray[i];
}
for (int j = 0; j < secondLength; j++)
{
splicedArray[j + copyLength] = secondArray[j];
}
for (int k = 0; k < firstLength - copyLength; k++)
{
splicedArray[k + copyLength + secondLength] = firstArray[k + copyLength];
}
return splicedArray;
}
void arrayPrint(int toPrint[])
{
for (int i = 0; i < sizeof(toPrint) / sizeof(*toPrint); i++)
{
if ((i % 10) == 9)
cout << toPrint[i] << endl;
else
cout << toPrint[i] << ", ";
}
}

Combining C_Raj's answer, vinodsaluja's and Wander3r's comments:
you are allocating first and second arrays twice, once is enough, actually more is memory leak (vinodsaluja).
Logically, since thirdarray is a combination of first and second arrays, its length should be sum of both array lengths, which is firstlength+secondlength not copylength. This is where heap corruption occurs (vinodsaluja).
Finally ararys should be deallocated with delete[] (Wander3r).
C_Raj's code is what the result should be so I'm not copying it.

Related

How to delete the new array in c++?

I have created a new point function in c++, where I create a new array by Dynamic memory allocation. However, when I want to delete the array in main function, it reports errors like:
'Assessment_1.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\ucrtbased.dll'
'Assessment_1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'.
The thread 0x22dc has exited with code 0 (0x0).
HEAP[Assessment_1.exe]: Invalid address specified to RtlValidateHeap( 00050000, 0005F25C )
Assessment_1.exe has triggered a breakpoint.
The return_array.cpp contains the function in which user inputs the keyboards.
#include<iostream>
#include <conio.h>
using namespace std;
//const static int length = 3;
int* input() {
//static int number[length]; fixed length for input
static int* number_array;
int number_length = 30;
int index = 0;
number_array = new int[number_length];
cout << "enter (ESC) to escape the program!" << endl;
while (_getch() != 27)
{
cout << "Input your number " << index << " elment: " << endl;
cin >> number_array[index];
index = index + 1;
cout << endl;
}
return number_array;
}
The practice.cpp contains the main function and the evaluation function of two vectors. The bug is when I add the delete []vector_1;.
#include <vector>
#include<iostream>
#include"myFunctions.h"
using namespace std;
const static int length = 3;
bool same_vec(vector<int> a, vector<int> b);
void main() {
vector<int> new_vector_1(length);
vector<int> new_vector_2(length);
int* vector_1 = input();
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1;
}
delete []vector_1;
for (int i = 0; i < length; i++) {
cout << " The result of vector_1: " << new_vector_1[i] << endl;
}
int* vector_2;
vector_2 = input();
for (int i = 0; i < length; i++) {
new_vector_2[i] = *vector_2;
vector_2 = vector_2 + 1;
}
delete []vector_2;
for (int i = 0; i < length; i++) {
cout << " The result of vector_2: " << new_vector_2[i] << endl;
}
bool qax = same_vec(new_vector_1, new_vector_2);
if (qax == false) {
cout << "the items are not match!"<<endl;
}
else {
cout << "the items are match!" << endl;
}
}
bool same_vec(vector<int> a, vector<int> b) {
//Evaluate the elements in the two vectors
bool flag = true;
int length_a = a.size();
int length_b = b.size();
vector<bool> new_bool(length_a);
for (int i = 0; i < length_a; i++) {
for (int j = 0; j < length_b; j++) {
if (a[i] == b[j]) {
new_bool[i] = true;
cout << a[i] << " " << b[j] << endl;
break;
}
}
}
for (int i = 0; i < new_bool.size(); i++) {
if (new_bool[i] == false) {
flag = false;
}
}
return flag;
}
And the myFunction.h is my head file.
#pragma once
int* getRandom();
int* input();
Can someone helps to solve the problem? I know one solution is delete the line of delete []vector_1;. The solution may cause memory-leak.
You are changing the address stored in the vector_1 pointer, then trying to delete[] something that no longer corresponds to the pointer returned by the new operator in your input function.
So, instead of this loop:
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1; // This line changes the pointer!
}
delete []vector_1; // And, here, the pointer is NOT what "new" gave you!
Use something like this, instead:
for (int i = 0; i < length; i++) {
new_vector_1[i] = vector_1[i]; // You can use the [] operator on the pointer
cout << *vector_1 << endl;
// vector_1 = vector_1 + 1; // Remove this line, as it's causing the problem!
}
delete []vector_1;
Also, you have exactly the same problem in the loop that deals with the vector_2 pointer - and the same 'fix' will work there, too.
Note: If you don't want to use the [i] index operator, but rather use pointer 'arithmetic', then you can change:
new_vector_1[i] = vector_1[i];
to:
new_vector_1[i] = *(vector_1 + i);
This way, you are adding the value of i to the pointer without changing that pointer.

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.

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;

Sorting through array of pointers

When I try to display the test scores in the function sortArray, I can only access the memory address. How to I access the values of the scores?? Also is the sortArray function correct overall?
#include <iostream>
using namespace std;
void sortArray(int *[], int);
int main()
{
int *testScores = nullptr;
//dynamically allocate an array
int scoreNUMS;
int score;
cout << "Please enter the total number of test scores" << endl;
cin >> scoreNUMS;
testScores = new int[scoreNUMS];
//dynamically allocates an array large enough to hold scoreNUMS
for(int i = 1; i <= scoreNUMS; i++)
{
cout << "Enter student " << i << "'s test score" << endl;
cin >> score;
if (score <= -1)
{
cout << "Please enter positive numbers only!" << endl;
}
*(testScores + i) = score;
//puts the input score in the array
}
sortArray(&testScores, scoreNUMS);
return 0;
}
Im not sure if the function below is correct because I was unaware where to place the * and the &
void sortArray(int *array[], int size)
{
bool swap;
int temp;
do
{
swap = false;
for(int count = 0;count < (size - 1); count++)
{
if(array[count] > array[count + 1])
{
temp = *array[count];
array[count] = array[count + 1];
array[count + 1] = &temp;
swap = true;
}
}
}while(swap);
for(int i = 0; i < size; i++)
cout << *(array + 1) << endl;
}
Error: Array consist scoreNUMS elements, the first one is testScores[0] - first index is zero. And last index is scoreNUMS-1
You must write
for(int i = 0; i < scoreNUMS; i++)
PS: You can use next prototype:
void sortArray(int [], int);
UPD: passing an array to a function is performed by passing a pointer to the first element of the array. (Your array does not copied when you pass it to function)
And run function by this way: sortArray(testScores, scoreNUMS);

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