I need to implement a push function for a dynamic array. Here's what I've done so far:
#include<iostream>
void printArr(int* arr, int n) {
for (int i = 0; i < n; i++)
std::cout << *(arr + i) << ' ';
}
void push(int* arr, int& size, int e) {
int* tmpArr = new int[size + 1];
for (int i = 0; i < size; i++) { // copying elements to the new array
*(tmpArr + i) = *(arr + i);
}
*(tmpArr + size) = e; // adding new element to the very end of the new array
arr = tmpArr;
size++;
}
int main() {
int size = 0;
int* arr = new int[size];
for (int i = 0; i < 5; i++) {
push(arr, size, i);
printArr(arr, size);
std::cout << std::endl;
}
delete[] arr;
return 0;
}
But it outputs only junk, not expected values.
Here is the output at each iteration.
-33686019
-33686019 -572662307
-33686019 -572662307 1320307911
-33686019 -572662307 1320307911 201336144
-33686019 -572662307 1320307911 201336144 14730656
I tried delete [] arr; before reassigning arr, but it throws a _CrtlsValidHeapPointer(block) exception after the first push() call.
The answer is most likely obvious, but I don't know why this is happening. What should I do to make this code work?
Also I'm wondering if I need to do something with the created tmpArr array after reassigning?
Related
I'm new to C++ and I've been doing bubbleSort, but when I want to show the numbers in the terminal, the leading number is a problem. Sorry for my bad english btw.
where am i doing wrong?
this is the code:
#include <iostream>
void printArray(int *myArr, int lenght) {
for (int i = 0; i < lenght; ++i) {
std::cout << myArr[i] << ", ";
}
}
int bubbleSort(int *myArr, int lenght) {
for (int i = 0; i < lenght; ++i) {
for (int j = 0; j < lenght-1; ++j) {
if (myArr[j] > myArr[j+1]) {
int temp = myArr[j];
myArr[j] = myArr[j+1];
myArr[j+1] = temp;
}
}
}
return *myArr;
}
int main() {
int myArr[] = {10,14,13,19,15,12,16,18,17,11};
int newArr = bubbleSort(myArr, 8);
printArray(&newArr, 8);
return 0;
}
this is what i get:
10, 10, 12, 13, 14, 15, 16, 18, there is no 19 and double 10s
and is there any eaiser way to get lenght of array in function? Thank you...
The problem is that you are confusing pointers with arrays with single integers.
int bubbleSort(int *myArr, int lenght) {
// ... not actually that important what happens here ...
return *myArr;
}
Your bubbleSort gets a pointer to first element of an array passed, you do some sorting and eventually you return the first element of that sorted array (return type is int!). This is wrong, or maybe not wrong but doesn't make much sense but the real drama will only come later...
...when here
int newArr = bubbleSort(myArr, 8);
printArray(&newArr, 8);
you copy that single integer returned from bubbleSort into newArr (an int), then take its address (still "ok") and then in printArray act like it points to an array which it doesn't (now it goes BooooM!).
myArr[i] in printArray is undefined behavior when i > 0, because myArr points to a single integer. It does not point to an array.
TL;DR: Do not use c-arrays. c-arrays are advanced C++, they are easy to get wrong and hard to get right. Use std::vector for dynamically sized arrays and std::array for compiletime sized arrays.
This is the idea that should work:
#include <iostream>
#include <vector>
using namespace std;
void printArray(vector<int> arr) {
for (auto & item : arr)
{
cout << item<<' ';
}
}
void bubbleSort(vector<int> &arr)
{
bool swapp = true;
while (swapp) {
swapp = false;
for (size_t i = 0; i < arr.size() - 1; i++) {
if (arr[i] > arr[i + 1]) {
arr[i] += arr[i + 1];
arr[i + 1] = arr[i] - arr[i + 1];
arr[i] -= arr[i + 1];
swapp = true;
}
}
}
}
void main() {
vector<int> arr = { 10,14,13,19,15,12,16,18,17,11 };
bubbleSort(arr);
printArray(arr);
}
Problem is - Wrong array size (i.e. 8) is passed to bubble sort function which produces wrong answer.
Use std::vector sothat superfluous length agrument can be avoided.
void bubbleSort(std::vector<int> & vec) {
for (int i = 0; i < vec.size(); ++i) {
...
}
}
bubbleSort(vec);
I want to resize the array multiple times.It does that the first time but after that, it throws me an error. When I do it the second time, I get an error _CrtIsValidHeapPointer(PUserData). Can someone help me out?
int main()
{
int size = 8;
int *arr = new int[size];
arr[1] = 25;
arr[2] = 30;
int count = 0; //to check size
for (int i = 0; i < size; i++)
{
count = count + 1;
}
cout << count << endl;
resize(arr, size);
int new_count = 0; //to confirm size change
for (int i = 0; i < size; i++)
{
new_count = new_count + 1;
}
cout << new_count << endl;
resize(arr, size);
int new_count2 = 0; //to confirm size change
for (int i = 0; i < size; i++)
{
new_count2 = new_count2 + 1;
}
cout << new_count2 << endl;
return 0;
}
void resize(int *a,int &size)
{
int newsize = 2 * size;
int *arr_new = new int[newsize];
for (int i = 0; i < size; i++) //copy everything
{
arr_new[i] = a[i];
}
size = newsize; //new value of size
delete [] a;
a = arr_new; //Pointer pointing to new array
delete arr_new;
}
There are two problems with this code:
void resize(int *a,int &size)
{
[...]
delete [] a;
a = arr_new; //Pointer pointing to new array
delete arr_new; // huh????
}
The first problem is that you are calling the delete operator twice; the first call deletes the old array (which makes sense), but then you attempt to delete the newly allocated array also (via delete arr_new). How is the caller going to able to use the newly allocated array when resize() has already deleted it before it returned?
The second problem is that you set a to point to the new array (i.e. a = arr_new;) but a is a local function-argument that goes out of scope when resize() returns, so the calling code will never see its new value. I think you want this instead:
void resize(int * & a,int &size) // note the & before a!
Passing a by reference will allow the caller to see a's new value after resize() returns.
I have this program that makes and populates an array. Then it is sent to a function called reverse, which reverses the order in the array. The compiler keeps giving errors. I'm not quite sure why.
CODE
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i];
array[size-i] = temp;
} // end of for loop
} // end of reverse
int main( int argc, char** argv ) {
int array[8];
// get and print size of the array
int size = sizeof(array) / sizeof(array[0]);
printf("Size is %d\n", size);
// populate array
for (int i = 0; i < size; i++) {
array[i] = i;
} // end of for loop
// display array before reversing
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
} // end of for loop
// new line
printf("\n");
// reverse the array
reverse(&array, size);
// display the array again after reversing
for (int i = 0;i < size; i++) {
printf("%d ", array[i]);
} // end of for loop
} // end of main
It keeps giving me this error
main.cc:17:14: error: indirection requires pointer operand ('int' invalid)
int temp = *array[i];
^~~~~~~~~
main.cc:18:3: error: indirection requires pointer operand ('int' invalid)
*array[i] = *array[size-i];
^~~~~~~~~
main.cc:18:15: error: indirection requires pointer operand ('int' invalid)
*array[i] = *array[size-i];
^~~~~~~~~~~~~~
main.cc:19:3: error: indirection requires pointer operand ('int' invalid)
*array[size-i] = temp;
^~~~~~~~~~~~~~
4 errors generated.
make: *** [main.o] Error 1
I did solve this problem a little differently, maybe you will use this code:
#include <iostream>
void displayArray(int table[], int size);
void rev(int table[], int size);
void fillTheArray(int table[], int size);
int main(int argc, char** argv) {
int myArray[8];
int size = sizeof(myArray) / sizeof(myArray[0]);
std::cout << "Array size is: " << size << std::endl;
fillTheArray(myArray, size);
displayArray(myArray, size);
std::cout << std::endl;
rev(myArray, size);
displayArray(myArray, size);
std::cin.get();
return 0;
}
void fillTheArray(int table[], int size) {
for (int i = 0; i < size; i++) {
table[i] = i;
}
}
void displayArray(int table[], int size) {
for (int i = 0; i < size; i++) {
std::cout << table[i] << " ";
}
std::cout << std::endl;
}
void rev(int table[], int size) {
int *start = table;
int *end = table + (size - 1);
for (int i = 0; i < size; i++) {
if (start < end) {
int temp = *end;
*end = *start;
*start = temp;
}
start++;
end--;
}
}
I can see two errors in this code. First is: wrong way of passing parametr to function:
// reverse the array
reverse(&array, size);
you should do this just like this(array name is pointer to first element of this array):
reverse(array, size);
Second problem is with reverser - you try to access some random memory outside arrar range:
array[i] = array[size-i];
Remember that in C++ array index's start with 0 not 1. So if your array is size of 8 - largest insext of this array is 7 (0, 1, 2, 3, 4, 5, 6, 7). Your code should look like this:
array[i] = array[size -i -1];
And it should work as you expected.
It is my solution with pointers:
void reverse(int arr[], int count)
{
int* head = arr;
int* tail = arr + count - 1;
for (int i = 0; i < count/2; ++i)
{
if (head < tail)
{
int tmp = *tail;
*tail = *head;
*head = tmp;
head++; tail--;
}
}
for (int i = 0; i < count; ++i)
{
std::cout << arr[i] << " ";
}
}
or just use functions build in C++: std::reverse in 'algorithm' library.
It's a lot of examples on stackoverflow with this kind of examples:
Reverse Contents in Array
You have fixed most of the compiler errors in your code except one.
The line
reverse(&array, size);
should be
reverse(array, size);
After that is fixed, you have to fix logic errors in reverse.
You are using the wrong index for accessing the upper half of the array.
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i]; // When i is 0, you are accessing array[size]
// That is incorrect.
array[size-i] = temp;
} // end of for loop
} // end
You need to use
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i-1];
array[size-i-1] = temp;
}
}
Another way to approach the algorithm would be to use two indices.
void reverse(int* array, int size) {
for (int i = 0, j = size-1; i < j; ++i, --j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Working program: http://ideone.com/ReVnGR.
You're passing **int instead of *int to the reverse method:
reverse(&array, size);
Pass it like that:
reverse(array, size);
void insert(int*arr, int element,int index)
{
if (index < SIZE)
{
arr[index] = element;
}
else
{
int* new_array = new int[SIZE + 1];
int i = 0;
for (i = 0; i < SIZE; i++)
{
new_array[i] = arr[i];
}
new_array[i] = element;
SIZE++;
printArray(new_array);
}
}
I have made an insert function in C++ that will insert values at specific indices of the array.After index gets increased I made a new array and copied values from the smaller array into it.
Problem is that printArray function which is just looping to print the array does well when it is called inside the insert function otherwise when I called printArray from the main last value of the array was garbage why is that?
You need to delete the old array and return the new array in its place, e.g.:
void insert(int* &arr, int element, int index) // <<< make `arr` a reference so that we can modify it
{
if (index < SIZE)
{
arr[index] = element;
}
else
{
int* new_array = new int[SIZE + 1];
for (int i = 0; i < SIZE; i++)
{
new_array[i] = arr[i];
}
new_array[SIZE] = element;
SIZE++; // <<< NB: using a global for this is not a great idea!
delete [] arr; // <<< delete old `arr`
arr = new_array; // <<< replace it with `new_array`
}
}
LIVE DEMO
Note that all this explicit low level management of your array goes away if you start using proper C++ idioms, such as std::vector<int> instead of C-style int * arrays.
In the implementation below of mergesort, the input pointer inputIntArray is somehow kept from being destroyed and winds up pointing to the sorted values pointed by sortedArray. As it is, I thought inputIntArray would not point to anything given the call delete[] intArray; just before the last merge. Could anyone please shed some light on this? Thank you.
#include <iostream>
using namespace std;
int* getSubArray (int*,int,int);
int* merge(int*,int*,int,int);
int* mergeSort ( int* intArray , int n ) {
if (n==1){
return intArray;
}
else {
int m = n/2;
int* leftArray = mergeSort ( getSubArray (intArray,0,m-1) , m );
int* rightArray = mergeSort ( getSubArray (intArray,m,n) , n-m );
delete[] intArray;
return merge(leftArray,rightArray,m,n);
}
}
int* getSubArray ( int* intArray , int start , int end ){
int n = end - start + 1;
int * subIntArray = new int [ n ];
for (int i=0;i<n;i++){
subIntArray[i]=intArray[i+start];
}
return subIntArray;
}
int* merge(int* leftArray, int* rightArray, int m, int n){
int* intArray = new int[n];
int i=0 , j=0;
for (int k=0;k<n;k++){
if ( i == m && j == n ) {
break;
}
if (leftArray[i]<=rightArray[j] && i < m){
intArray[k]=leftArray[i++];
}
else {
intArray[k]=rightArray[j++];
}
}
delete[] leftArray;
delete[] rightArray;
return intArray;
}
int main () {
int* inputIntArray = new int[6]{1,5,6,2,3,7};
for (int i=0;i<6;i++){
cout << inputIntArray[i];
}
cout << endl;
int* sortedArray = mergeSort ( inputIntArray , 6 );
for (int i=0;i<6;i++){
cout << inputIntArray[i];
}
cout << endl;
for (int i=0;i<6;i++){
cout << sortedArray[i];
}
cout << endl;
delete[] sortedArray;
}
Here is the output:
156237
123567
123567
You have this call:
int* sortedArray = mergeSort(inputIntArray, 6);
In the process of executing that code, you do:
delete[] inputIntArray;
sortedArray = new int[6];
It is certainly possible that sortedArray gets the same address as the just deleted inputIntArray.