C++ Memory leak error when resizing C++ dynamic array - c++

The code below converts lets say array 3,9,3 to sorted array of integers 3,3,3,3,3 by converting 9 into sum of maximum possible parts.
The link to code/algorithm used in this code is answered at
https://stackoverflow.com/a/75331557/21145472
I am struck in this C++ code. When I ran it yesterday it was fine but today it gives memory leak error when function resizeArray() is run third time.
Please help fix this memory leak
#include<cmath>
#include <algorithm>
#include <iterator>
using namespace std;
void resizeArray(int *orig, int size, int newSize) {
int *resized = new int[newSize];
for (int i = 0; i < size; i ++)
resized[i] = orig[i];
delete [] orig;
orig = resized;
}
int main(){
int n = 3;
int *arr = new int[n];
int arrLength = n;
arr[0] = 3;
arr[1] = 9;
arr[2] = 3;
int *arrSorted = new int[0];
int sortedArrayLength = 0;
int temp;
unsigned long long int limit = 10e4;
long long parts = 0;
int extra = 0;
int mainArrayIndex = 0;
for(int i = 0; i<n/2; i++){
temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}
for(int i = 0; i < n; i++){
parts = floor((arr[i] - 1) / (limit)) + 1;
limit = arr[i] / parts;
extra = arr[i] % parts;
for(int index = 0; index < extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit+1;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
for(int index = 0; index < parts - extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
}
cout << "Array sorted steps taken" << " " << sortedArrayLength - arrLength;
cout << endl;
for(int i = 0; i < sortedArrayLength; i++){
if(i == 0)
cout << "[";
cout << arrSorted[i];
if(i < sortedArrayLength - 1)
cout << ", ";
if(i == sortedArrayLength - 1)
cout << "]";
}
delete []arr;
delete []arrSorted;
}

Your helper function's orig = resized; doesn't reassign your main function's arrSorted as you intend. Use a reference:
void resizeArray(int *&orig, ...) {
(That and the lack of including iostream are the only correctness issues I see, and this fix got rid of the error.)

Related

access violation in pointer allocation

I want to put random data into arr (pointer allocation). How can I put data into that dynamic allocation?
typedef unique_ptr<unique_ptr<int[]>[]> uniquePtr;
uniquePtr arr = make_unique<unique_ptr<int[]>[]>(size);
srand(time(NULL));
cout << "size: " << endl;
cin >> size;
int max = size * size;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
arr[i][j] = rand() % max; //error!
}
}
Type of arr[i][j] is int.
When I tried this code,
arr[i][j] = new int(rand() % max);
but, the error is
arr[i][j] is int type and new int(~) is int* type
I want to put random int data into arr allocation.
The problem is you did not dynamically allocate the second dimension.
#include <iostream>
#include <memory>
using namespace std;
int main() {
int size = 5;
typedef unique_ptr<unique_ptr<int[]>[]> uniquePtr;
uniquePtr arr = make_unique<unique_ptr<int[]>[]>(size);
srand(time(NULL));
cout << "size: " << endl;
cin >> size;
int max = size * size;
for (int i = 0; i < size; i++) {
// Dynamically allocate the row
arr[i] = make_unique<int[]>(size);
for (int j = 0; j < size; j++) {
arr[i][j] = rand() % max;
}
}
return 0;
}
I put this online here: https://ideone.com/llAvTD

I am unable to get my code to get the stride of 7 to work properly C++

The question I am trying to solve is the following:
Write a function that traverses (and prints) the element of an array with stride =7. To do this the update part in the loop will be i= (i+7) % n, where n is the array size.
Would this function visit all elements of the array? Try different array sizes to check when it is impossible to traverse all elements.
The code that I wrote below doesn't print the correct values in the arry even if the value of i is correct.
Can anyone help, I would really appreciate it.
#include <fstream>
#include <stdlib.h>
using namespace std;
int* CreateArray(int n);
void StrideArray(int arr[], int n);
int main()
{
int* arr = new int[3];
arr = CreateArray(3);
cout << "The Elements In The Array Are: " << endl;
for (int i = 0; i < 3; i++)
{
cout << arr[i] << " ";
}
cout << endl;
StrideArray(arr, 3);
cout << "The Elements In The Array Stride 7 Are: " << endl;
for (int i = 0; i < 3; i++)
{
cout << arr[i] << " ";
}
delete[] arr;
return 0;
}
int* CreateArray(int n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = (rand() % 100);
}
return arr;
}
void StrideArray(int arr[], int n)
{
int i = 0;
for (int j = 0; j < n; j++)
{
i = (i + 7) % n;
arr[j] = arr[i];
}
}
The problem is in StrideArray you read back the modified values of arr.
void StrideArray(int arr[], int n)
{
int i = 0;
int puffer=new int[n];
for (int j = 0; j < n; j++)
{
i = (i + 7) % n;
puffer[j] = arr[i];
}
for (int j = 0; j < n; j++){
puffer[j] = arr[j];
}
debete[] puffer;
}
Is a good way to write the function.
Also it visits all element only if n isn't dividable by 7. So if n is not 7,14,21,...
Also to use cout you have to #include <iostream>
Your StrideArray function needs fixing; you are iterating over j but using i to index, which remains constant; and you are reassigning value at one index to another where as you are supposed to print it:
void StrideArray(int arr[], int n)
{
int i = 0;
for (int j = 0; j < n; j=j+7)
{
cout << arr[j] << endl;
}
}
I modified the rest of your code for demo:
#include <iostream>
#include <stdlib.h>
using namespace std;
int* CreateArray(int n);
void StrideArray(int arr[], int n);
int main()
{
int* arr = new int[3];
arr = CreateArray(21);
cout << "The Elements In The Array Are: " << endl;
for (int i = 0; i < 21; i++)
{
cout << arr[i] << " ";
}
cout << endl;
StrideArray(arr, 21);
delete[] arr;
return 0;
}
int* CreateArray(int n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = (rand() % 100);
}
return arr;
}

I'm trying to print my array but i'm not getting my desired result

I'm fairly new to programming and was trying to create a program which creates a one dimensional array with random numbers from a certain range and then prints it out. I managed to make a function to create the array but I'm having trouble actually printing out the array I made. I have a general idea of what the problem might be but no clue as to how to fix the code.
Here is the code in question:
#include <iostream>
using namespace std;
int *create(int n)
{
int *arr = new int [n];
for (int i = 0; i > n; i++)
{
arr[i] = rand() % 100;
}
}
int main ()
{
int n = 12;
int *arr = create(n);
cout << "this is the array: ";
for (int i = 0; i > n; i++)
{
cout << arr[i] << " ";
};
delete[] arr;
return 0;
}
There are two errors in your code:
You are not returning your array from create()
Your loop condition is incorrect.
Fixed code:
#include <iostream>
using namespace std;
int *create(int n)
{
int *arr = new int [n];
for (int i = 0; i < n; i++)
{
arr[i] = rand() % 100;
}
return arr;
}
int main ()
{
int n = 12;
int *arr = create(n);
cout << "this is the array: ";
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
};
delete[] arr;
return 0;
}
I dont see how you code compiles.
You are not returning anything from function.
both your loop conditions should be <n
This way is works but your design is very poor, unless you are just learning handling pointers.
#include <iostream>
using namespace std;
int* create(int n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = rand() % 100;
}
return arr;
}
int main()
{
int n = 12;
int* arr = create(n);
cout << "this is the array: ";
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
};
delete[] arr;
return 0;
}
The only missing part in your code - you are not returning your arr variable from your create function.
int *create(int n)
{
int *arr = new int [n];
for (int i = 0; i > n; i++)
{
arr[i] = rand() % 100;
}
return arr;
}
This way it will work:)
You made a mistake in the loop. you used '>' instead of '<' line 22 should be.
for (int i = 0; i < n; i++)
The loop stopped before the first iterations because i=0 was smaller than n=12.

Applying selection sort on an array of integers

int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i<size-1; i++){
int temp = arr[i];
for(int j = i+1; j < size; j++){
if(arr[j] < temp){
temp = arr[j];
}
}
swap(temp, arr[i]);
}
I am trying to apply the selection sort algorithm on the given array, but the output I am getting is only [1,1,1,1,1,1], I am finding the minimum element through the inner loop, Ican't figure out what is going wrong?
Slightly modified your code;
You need to pass reference(address) to both elements to take place of swapping contents
int arr[] = { 7, 1, 10, 8, 3, 11, 0, 12, 5, 8 };
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i < size; i++)
{
auto temp = std::min_element( arr + i, arr + size );
std::swap( arr[i], *temp );
}
You have to add algorithm header to use std::min_element
int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i<size-1; i++){
int temp = arr[i];
int pos = i;
for(int j = i+1; j < size; j++){
if(arr[j] < temp){
temp = arr[j];
pos = j;
}
}
if(pos != i)
std::swap(arr[pos], arr[i]);
}
This should work.
It is suggested not to use using namespace std;. There is a plethora of reasons why you should not; that I will not mention.
By the way I tried to keep some of your variables the same but to be honest, I didn't. It is better to create variable names that explain what the code is doing. It makes your code a lot more legible and readable.
So opt out of one letter variables. It is fine in for loops, however this is a special case.
Now, here is another alternative suggested by #user4581301 & #Swift -Friday Pie. This method is using std::size using c++17.
For example:
#include <iostream>
#include <utility> // to use the swap() function.
#include <iterator> // to use std::size() function.
int main()
{
int arr[] = { 7,4,10,8,3,1 };
// This --> int size = sizeof(arr) / sizeof(arr[0]); is archaic.
const int length = static_cast<int>(std::size(arr)); // Call this something other than "size"; you can run into issues.
// We use static_cast<int> as a implicit conversion, and the obvious std::size(arr)).
// Going through the elements
for (int StartOfIndex = 0; StartOfIndex < length - 1; ++StartOfIndex)
{
// smallest is the index of the smallest element we’ve encountered this iteration
int smallest = StartOfIndex;
// Looking for a smaller element..
for (int current = StartOfIndex + 1; current < length; ++current)
{
// if we found an element smaller than our last; take note.
if (arr[current] < arr[smallest])
smallest = current;
}
// swap StartOfIndex with smallest.
std::swap(arr[StartOfIndex], arr[smallest]);
}
//Prints array.
for (int index = 0; index < length; ++index)
std::cout << arr[index] << " ";
std::cout << "\n";
return 0;
}
Output: 1 3 4 7 8 10
The first mistake you made in writing for loop's condition, don't use swap(temp, array[i]); yet try to get the basics first.
#include <iostream>
using namespace std;
int findsmall(int arr[], int i, int size){
int s, pos, j;
s = arr[i];
pos = i;
for(j = i+1; j < size; j++){
if(arr[j] < s){
s = arr[j];
pos = j;
}
}
return pos;
}
int main() {
int arr[] = {7,4,10,8,3,1};
int size = sizeof(arr) / sizeof(arr[0]);
int smallnum;
int temp;
int count = 0;
cout << "Original array: ";
for(int i = 0; i < size; i++){
if(i < size - 1){
cout << arr[i] << ", ";}
else{
cout << arr[i];
}
}
cout << endl;
for(int i = 0; i < size; i++){
smallnum = findsmall(arr,i, size);
temp = arr[i];
arr[i] = arr[smallnum];
arr[smallnum] = temp;
count++;
}
cout << "Sorted array: ";
for(int i = 0; i < size; i++){
if(i < size - 1){
cout << arr[i] << ", ";}
else{
cout << arr[i];
}
}
cout << endl;
return 0;
}
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element with the first element
swap(&arr[min_idx], &arr[i]);
}
}
selectionSort(arr,size);
This should work.

Resizing dynamic array in c++

I have some code that is producing unexpected results. Here is the code:
#include <iostream>
using namespace std;
int **nums;
int size;
void A(int** arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
arr = resize;
size *= 2;
delete[] resize;
}
int main()
{
size = 10;
nums = new int*[size];
for(int i = 0; i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
}
The function A(int** arr) works fine as far as I can tell and actually resizes the array. However, in the last for loop in main(), when the array is printing, the first two elements of the array are not 0 and 1 like it is supposed to be. Here is the result I am getting:
0
1
2
3
4
5
6
7
8
9
16331248
16331712
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Those first two ints after the space are different each time the program is executed. After some debugging I found out that the first two elements print correctly until the iterator i=13 in the second to last for loop in main(). Then the first two elements in the array take on some large numbers. I am not sure why this is happening and I have been working on this for a couple of hours now :( Any help is appreciated.
A() is not modifying nums to point at the new array. Even if it were, it is deleting the new array, so nums would end up pointing at invalid memory. You need to declare the arr parameter as a reference, and delete the old array instead of the new array:
void A(int** &arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
For what you are attempting, I think you have too much indirection. Try removing a level:
#include <iostream>
using namespace std;
int *nums;
int size;
void A(int* &arr)
{
int *resize;
resize = new int[size*2];
for(int i = 0; i < size; i++)
resize[i] = arr[i];
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
int main()
{
size = 10;
nums = new int[size];
for(int i = 0; i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
delete[] nums;
}
Since you are using C++, you should be using a std::vector instead of a raw array, then you can eliminate A() altogether:
#include <iostream>
#include <vector>
using namespace std;
vector<int> nums;
int main()
{
nums.resize(10);
for(int i = 0; i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
nums.resize(nums.size()*2);
cout << endl << endl;
for(int i = (nums.size() / 2); i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
}
First of all, your function, A, does not resize anything. It prints a newline character to standard output, it multiplies the global size variable by 2, and then it leaks some memory. That's it.
Now, because it multiplies size by 2 (going from 10, to 20), you run into a problem, here:
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
Here, you are trying to access elements 10 through 19 of the array which nums points to. But the array which nums points to only has 10 elements (numbered 0 through 9), so your code has undefined behavior.