Resizing dynamic array in c++ - 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.

Related

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

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.)

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

Accessing a dynamically created multi dimensional array with pointers arithmetic

I would like to understand how does it works to scan a dynamically allocated two-dimensional array using pointers arithmetics?
I can't figurate why in my example pointer arithmetic isn't returning the same results as using array indexing.
Here is my implementation:
#include <iostream>
using namespace std;
void init_matrix(int ** m, int size);
void print_matrix(int ** m, int size);
void print_matrix_pointers(int ** m, int size);
int main (){
srand (time(NULL));
int size = 3;
int ** dynamic_matrix = new int * [size];
for (int i = 0; i < 10; i++) {
dynamic_matrix[i] = new int [size];
}
init_matrix(dynamic_matrix, size);
cout << "Dynamic matrix accessed using square brackets ([i][j]): " << endl;
print_matrix(dynamic_matrix, size);
cout << "Dynamic matrix accessed using pointers arithmetics: " << endl;
print_matrix_pointers(dynamic_matrix, size);
return 0;
}
void init_matrix(int ** m, int size) {
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
m[i][j] = rand()%10;
}
}
}
void print_matrix(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << m[i][j] << " ";
}
cout << endl;
}
}
void print_matrix_pointers(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << *(*m + (i * size) + j) << " "; //
}
cout << endl;
}
cout << endl;
}
For instance if size was 3 I would get this output.
Dynamic matrix accessed using array indexing ([i][j]):
3 3 4
9 5 9
4 9 4
Dynamic matrix accessed using pointers arithmetics:
3 3 4
32735 9 5
9 32735 4
With *(*m + (i * size) + j) you treat m as a contiguous array of values, which it isn't. It's more like a jagged array. You need to treat it like the array of pointers it really is, like *(*(m + i) + j).
Two typos in your code:
int size = 3;
int ** dynamic_matrix = new int * [size];
for (int i = 0; i < 10; i++) {
dynamic_matrix[i] = new int [size];
}
size is 3 but you write 10 elements. That is undefined behavior.
Then you are advancing the pointer wrongly.
void print_matrix_pointers(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << *( *(m + i) + j) << " "; //
}
cout << endl;
}
cout << endl;
}
m points to an array of pointers to int. You have to increment m by i to get to the i-th row. Then you want to access the jth element of the array pointed to by m[i], hence you have to first dereference m+i then add j to get the address of jth element.

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;
}

Heap corruption detected error in C++

Here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
int** arr=NULL;
int num=0;
cin >> num;
int* big=NULL;
arr = new int*[num];
for (int i = 0; i < num; i++) {
arr[i] = new int[5];
}
big = new int[num];
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
while (1) {
cin >> arr[i][j];
if (arr[i][j] >= 0 && arr[i][j] < 100)
break;
}
}
}
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
if (big[i] < arr[i][j]) {
big[i] = arr[i][j];
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
delete[]big;
for (int i = num-1; i>=0; i--) {
delete[]arr[i];
}
delete[]arr;
return 0;
}
When I run this code, it says that there are heap corruption error (heap corruption detected). I think it means that there are some errors at 'new' or 'delete' parts in my codes, but I cannot find them. I hope someone to answer. Thanks.
Error is here:
big = new int[num];
...
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
So when you have num less than 5 you are writing outside the array.
Anyway you are using C++ so use vector for such tasks.
#include<iostream>
#include<cstdlib>
#include<vector>
using namespace std;
int main() {
vector<vector<int>> arr;
int num=0;
cin >> num;
arr.resize(num, vector<int>(5));
for (auto &row : arr) {
for (auto &cell : row) {
while (1) {
cin >> cell ;
if (cell >= 0 && cell < 100)
break;
}
}
}
vector<int> big(arr.size());
for (int i = 0; i < arr.size(); i++) {
for (auto &cell : arr[i]) {
if (big[i] < cell) {
big[i] = cell;
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
return 0;
}
In many places in your code, you're indexing your big array using indexes from 0 to 5, while the array is allocated using user input, if user input was 4 for example, your code is undefined behavior.
If you're using c++, you shouldn't be manually allocating the arrays, use std::vector instead, it will take care of managing memory for you, so you don't have to new and delete memory yourself.
With std::vector, your code would look somewhat like this.
std::vector<std::vector<int>> arr;
std::vector<int> big;
cin>>num;
arr.resize(num, std::vector<int>(5));
big.resize(5);
You will also be able to use at method to access elements while bound-checking, and size method to get the number of elements of the array.