C++ Populate new elements in a resized dynamic array - c++

While ripping through my homework, I've run across a bug I can't figure out. I've read and played around it but I can't figure out what I'm doing wrong.
The user enters an int pointer array, then the code is supposed double the size of the array and populate the new elements with 0. The problem is that the new elements aren't 0. What am I doing wrong and what are these numbers being printed, addresses?
Output:
Enter array size: 3
Enter Element 0: 10
Enter Element 1: 11
Enter Element 2: 12
Entered Array:
Element 0/3 is 10
Element 1/3 is 11
Element 2/3 is 12
Resized Array:
Element 0/6 is 10
Element 1/6 is 11
Element 2/6 is 12
Element 3/6 is -33686019
Element 4/6 is 1196933248
Element 5/6 is 201354124
Press any key to continue . . .
Code:
#include <iostream>
#include <string>
using namespace std;
int *createArray(int size)
{
int *newArray;
newArray = new int[size];
for( int i = 0; i < size; i++){
cout << "Enter Element " << i << ": ";
cin >> newArray[i];
}
return newArray;
}
int *dblArraySize ( int *myArray, int& size)
{
int *newArray;
newArray = new int[size*2];
for (int i = 0; i < size; i++)
newArray[i] = myArray[i];
for (int i = size; i < size*2; i++){
newArray[i] = 0;
}
size = size*2;
return newArray;
}
void displayArray(int *anArray, int size, string msg)
{
cout <<endl << endl << msg;
for (int i = 0; i<size;i++){
cout << endl << "Element " << i << "/" << size << " is " << anArray[i];
}
}
int main ()
{
int size,
*mainArray;
cout << "Enter array size: ";
cin >> size;
mainArray = createArray(size);
displayArray(mainArray,size, "Entered Array:");
dblArraySize(mainArray,size);
displayArray(mainArray,size, "Resized Array:");
}

The problem is that you are returning the newArray from dblArraySize, but never using it. You never modify mainArray
dblArraySize(mainArray,size);
Should be:
mainArray = dblArraySize(mainArray,size);
Also note: You are forgetting to release the memory for the original array.

Related

where can I use try catch in dynamic memory allocation program?

i'm new to the world of c ++ so i need a little help. I wrote a program with dynamic memory allocation that does the following:
Print a message to the user to enter the array size
User input the array size
Filling an array of n elements with zeros
Printing an array
Print a message to the user to enter n elements
User input n elements and their placement in the array
Print the total number of even numbers entered
Print the total number of odd numbers entered
Delete a dynamic array
#include <iostream>
using namespace std;
int main()
{
int even_counter = 0;
int odd_counter = 0;
int* a = NULL;
cout << "Enter size of an array:"<< endl;
int n;
cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
cout << a[i]<<endl;
}
cout<< "Enter the elements of an array:"<<endl;
for (int i=0; i<n; i++) {
cin>>a[i];
}
for (int i=0; i<n; i++) {
if (i % 2 == 1) {
even_counter = even_counter + 1;
}
if (i % 2 == 0) {
odd_counter = odd_counter + 1;
}
}
cout << You've entered " << even_counter << " even and " << odd_counter <<
" odd numbers." << endl;
delete [] a;
a = NULL;
return 0;
}
I wanted to ask if my program is completely correct and how could I use the try catch command in this program. Thanks a lot

Checking for duplicates in an array using for loop

I am trying to check whether there is any duplicate integer in the user input array. The problem is that the validation of the duplicate does not work properly and I have no idea why it is not showing the desired output. Following is the code:
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
{
cin >> arr[i];
}
cout << "Array : ";
for(int i = 0; i < length; i++)
{
arrValue = arr[i];
for(int k = i + 1; k < length; k++)
{
if(arr[i] == arr[k])
{
cout << "Duplicate found" << endl;
break;
}
else
{
cout << arrValue << " ";
}
}
}
delete[] arr;
}
Current result (assuming no duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 3 2 1
Array : 5 5 5 5 4 4 4 3 3 2
Expected result (assuming no duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 3 2 1
Array : 5 4 3 2 1
Current result (assuming duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 4 2 1
Array : 5 5 5 5 Duplicate found 4 4 3
Expected result (assuming duplicate in user input):
Enter the length: 5
Enter 5 integers for array : 5 4 4 2 1
Array : Duplicate found
I believe my loops is the source to the problem. The current result output 10 times and I do not understand why there will be so many same numbers appearing.
Do note that I am trying to apply the validation using loop only and not from C++ standard library.
The issue in your code is that you are printing out each array element every time a particular element is not matching another element. It seems that you only want to print out whether any duplicate values are found. For this, you can use a bool flag to indicate whether any element is duplicated:
bool found_dup = false;
for(int i = 0; i < length; i++)
for(int k = i + 1; k < length; k++)
if(arr[i] == arr[k])
{
found_dup = true;
break;
}
// else: don't print anything yet
and then at the end print out the array:
if (found_dup)
std::cout << "Duplicate found";
else
for(int i = 0; i < length; i++)
std::cout << arr[i] << " ";
You may achieve the program in a more enhanced way (where you don't need to define the length manually - notice the explanation given as comments in code):
#include <iostream> // for input/output operation
#include <vector> // for dynamic array management
#include <sstream> // to split the user inputs and assign them to the vector
#include <algorithm> // to sort the vector
#include <string> // to work with getline()
// using this statement isn't recommended, but for sake of simplicity
// and avoiding the use of std:: everywhere temporarily (for small programs)
using namespace std;
int main(void) {
vector<int> numbers;
vector<int> duplicates;
string input;
int temp;
// getting the user input as string
cout << "Enter the numbers: ";
getline(cin, input);
stringstream ss(input);
// splitting the user input string into integers and assigning
// them into the vector
while (ss >> temp)
numbers.push_back(temp);
// sorting the vector in increasing order
sort(numbers.begin(), numbers.end());
// getting the unique numbers (which are not repeated)
cout << "Unique numbers: ";
for (size_t i = 0, len = numbers.size(); i < len; i++) {
if (temp == numbers[i])
// if found a duplicate, then push into the 'duplicates' vector
duplicates.push_back(temp);
else
cout << numbers[i] << ' ';
temp = numbers[i];
}
// getting the duplicates
cout << "Total duplicates: ";
for (size_t i = 0, len = duplicates.size(); i < len; i++)
cout << duplicates[i] << ' ';
cout << endl;
return 0;
}
It'll output something like:
Enter the numbers: 1 4 8 9 3 2 3 3 2 1 4 8
Unique numbers: 1 2 3 4 8 9
Total duplicates: 1 2 3 3 4 8
Please change the if condition to something like this.
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
{
cin >> arr[i];
}
cout << "Array : ";
for(int i = 0; i < length; i++)
{
arrValue = arr[i];
for(int k = i + 1; k < length; k++)
{
if(arrValue == arr[k]) //change here.
{
cout << "Duplicate found" << endl;
break;
}
else
{
cout << arrValue << " ";
}
}
}
delete[] arr;
}
I would also suggest to use a map data structure. Map allows you to count the frequency of numbers, and thus detect duplicates in linear time.
map<int, int> m; // specify the key-value data-type.
for(int i = 0;i<length;i++)
{
m[arr[i]]++;
}
map<int, int>::iterator it; // an iterator to iterate over the datastructure.
for(it = m.begin();it!=m.end();it++)
{
if(it->second>1) //it->second refers to the value(here, count).
{
cout<<it->first<<" "; //it->first refers to the key.
}
}
Your loops are actually iterating n-1 times for first element, n-2 times for second element etc., where n is the length of your array. This is why for 5 element array you have printed 5 4 times.
But generally, if the purpose is to detect duplicates in the array, this strategy is not the best one. Please note that having exemplary array 4 3 4, with current approach you will correctly detect for the first 4 that the third element is also 4 but once you will move to the third element, it will be marked as ok since it is not checked with the first one element.
You may consider another strategy: create another array of the n size. Then iterate through your original array and for each element check if that element is already in the new array. If you detect the presence, you may raise duplicate event. Otherwise you can add this element to the array.
It doesn't work because you're trying to print the same value everytime you find a different one. I got here a solution with one more array that will store the array. It would work too with just one array.
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
int *noDuplicateArr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
cin >> arr[i];
cout << "Array : ";
bool duplicateFound = false;
int noDuplicateArrLen = 0;
for(int i = 0; i < length && !duplicateFound; i++)
{
arrValue = arr[i];
int k;
for(k = i + 1; k < length; k++)
{
if(arrValue == arr[k])
{
duplicateFound = true;
break;
}
}
if (k == length)
noDuplicateArr[noDuplicateArrLen++] = arrValue;
}
if (duplicateFound)
{
cout << "Duplicate found";
}
else
{
for (int i = 0; i < noDuplicateArrLen; i++)
{
cout << noDuplicateArr[i] << " ";
}
}
delete[] arr;
delete[] noDuplicateArr;
}
Here is the version with just one array:
#include <iostream>
using namespace std;
int main()
{
int length;
int arrValue;
cout << "Enter the length : ";
cin >> length;
int *arr = new int[length];
cout << "Enter " << length << " integers for array : ";
for(int i = 0; i < length; i++)
cin >> arr[i];
cout << "Array : ";
bool duplicateFound = false;
int noDuplicateArrLen = 0;
for(int i = 0; i < length && !duplicateFound; i++)
{
arrValue = arr[i];
int k;
for(k = i + 1; k < length; k++)
{
if(arrValue == arr[k])
{
duplicateFound = true;
break;
}
}
if (k == length)
arr[noDuplicateArrLen++] = arrValue;
}
if (duplicateFound)
{
cout << "Duplicate found";
}
else
{
for (int i = 0; i < noDuplicateArrLen; i++)
{
cout << arr[i] << " ";
}
}
delete[] arr;
}

Pointers as member data fields in C++ structs

#include <iostream>
using std::cout;
using std::cin;
void printArray(int A[], int size) {
for(int i = 0; i < size; i++) {
cout << A[i] << "\t";
}
cout << "\n";
}
struct Array {
int *A;
int size;
int length;
};
void display(Array *arr) {
for(int i = 0; i < arr->length; i++) {
cout << arr->A[i] << "\t";
}
cout << "\n";
}
void fillArray(Array *arr) {
for(int i = 0; i < arr->length; i++) {
cin >> arr->A[i];
}
}
void add(Array *arr, int x) {
if(arr->length < arr->size) {
arr->A[++arr->length] = x;
}
}
int main() {
Array arr;
cout << "arr.size before initializing: " << arr.size << "\n"; // gives a garbage value
cout << "Enter the size of the array: ";
cin >> arr.size;
cout << "Output of arr variable &arr: " << &arr << "\n";
arr.A = new int[arr.size];
cout << "arr.length before initializing: " << arr.length << "\n"; // gives garbage value
cout << "How many elements do you want to enter: ";
cin >> arr.length;
fillArray(&arr); //This is not pass by value but pass by reference because
display(&arr); // this function displays the values of arr
add(&arr, 15);
cout << "The length of the array after adding: " << arr.length << "\n";
display(&arr);
printArray(arr.A, arr.length);
}
The output of this program is like this:
$ ./array_adt
arr.size before initializing: -140717888
Enter the size of the array: 10
Output of arr variable &arr: 0x7ffe4e0ec040
arr.length before initializing: 21932
How many elements do you want to enter: 5
4 6 7 3 2
4 6 7 3 2
The length of the array after adding: 6
4 6 7 3 2 0
4 6 7 3 2 0
I am highly confused why the element 15 isn't added to the array of the struct (which is actually a pointer which is initialised to an array in the heap). If someone can throw light on this it would be great for a many people as well as for understanding c++ concepts in depth.
Thanks a lot.
arr->A[++arr->length] = x;
should be
arr->A[arr->length++] = x;
Array indexes start at zero in C++, so the first element past the end of an array arr of size N is arr[N]. In other words 15 did get added to the array, just not in the right place.
Also your code leaks memory because the array allocated in main is never deleted. Correctly allocating dynamic memory is a big (and very important) topic. Consult your favourite C++ book, in particular you should research the rule of three

How do I change the size of an array and fill it with automated elements?

I have an array with set elements 1 - 10. I have decided the size of the array and I have decided the elements of the array. My question is, how do I create an array of size x and fill it with elements 1,2,3,4 . . .
//sets values of the array elements and print them.
cout << "Array should contain x integers set to 1,2,3" << endl;
// QUESTION: How can I change the size of the array and have
// have values automatically entered?
int array[] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i <= (sizeof(array) / sizeof(int)-1); ++i) {
// sizeof(array)/sizeof(int) = 36/4. ints are 4.
cout << "Element " << i << " = " << array[i] << endl;
}
cout << "The number of elements in the array is: "
<< sizeof(array) / sizeof(int) << endl;
cout << endl;
cout << endl;
you can use dynamic memory allocation approach for your array, there you can give as much size as you want. Thanks.
//Variable size of Array program to print Array elements
#include <iostream>
using namespace std;
int main()
{
cout << "Enter Array size x:" << endl;
int x = 0;
cin >> x;
int *ptrArray = new int[x];
//Inittialise Array
for (int i = 0; i < x; i++)
{
ptrArray[i] = i + 1;
}
//Print Array elemts
cout << "Array elements:";
for (int i = 0; i < x; i++)
{
cout << ptrArray[i] << endl;
}
delete[] ptrArray;
return 0;
}

Confusing error when deleting dynamically allocated array in C++

I am trying to implement a simple merge sort algorithm. What I am very confusing is that
I keep getting the following error message right after the "array2" is deleted.
"
free(): invalid next size (fast)
"
Please advise. Thank you very much!
#include <iostream>
#include <limits.h>
using namespace std;
void merge_sort(int*,int,int);
int main(){
//cout << "Max int: " << INT_MAX <<endl;
int n;
cin >> n;
int* array = new int(n+1);
for (int i=1; i<=n; i++)
cin >> array[i];
merge_sort(array,1,n);
cout << "--------------------------------------------" <<endl;
for (int i=1; i<=n; i++)
cout << array[i] <<endl;
}
void merge_sort(int* array,int p,int r){
cout << p << ' ' << r <<endl;
if (p == r)
return;
int q = int((p+r)/2);
merge_sort(array,p,q);
merge_sort(array,q+1,r);
//(p..q) and (q+1 .. r) sorted, then merge this two sorted array
int n1 = q-p+1;
int n2 = r-q;
cout << "Mark1 " <<n1<<' '<<n2<<endl;
int *array1;
array1 = new int(n1+1);
int *array2;
array2 = new int(n2+1);
for (int i=p; i<=q; i++)
array1[i-p] = array[i];
for (int i=q+1; i<=r; i++)
array2[i-q-1] = array[i];
array1[n1] = INT_MAX;
array2[n2] = INT_MAX; //CONSTANT, serve as sentinel
int p1 = 0;
int p2 = 0;
cout << "Mark2" << endl;
for (int i=p; i<=r; i++){
if (array1[p1]<array2[p2]){
array[i] = array1[p1];
p1++;
}else{
array[i] = array2[p2];
p2++;`enter code here`
}
}
cout << "Mark3" << endl;
delete [] array2;
cout << "Delete array2 " << endl;
delete [] array1;
cout << "Delete array1 " << endl;
}
The syntax
new int(n+1)
Creates a single int on the free-store and initialises it with n+1, and right away you access it out of bounds with array[1]. You want brackets:
new int[n + 1]
Which will create an array. The same goes for every other place like that in the program.
Also, since you are starting your loop at 1, the object array[0] is uninitialised and you get undefined behaviour if you access it, which you do. This is wasting an array element for nothing and setting up traps for yourself, I recommend you don't add 1 to the array size and start your indices from 0.