Using pointers to duplicate and grow an existing array - c++

I am failing to reach expected output when testing my 'grow'and 'subArray' functions. I've tried dereferencing back and forth in the function and also in main(). I'm wondering if there's something wrong with my memory allocation that is causing the lapse. I am extremely stuck and was hoping someone could potentially see something that I am missing, thanks.
#include <iostream>
#include <iomanip>
using namespace std;
bool isSorted(int *arr, int size){
for(int index = 0; index < size - 1; index ++){
if(*(arr + index) > *(arr + index + 1)){
return false;
}
}
return true;
}
double chain (int totalInches, int *feet, int *inches){
*feet = totalInches/12;
*inches = totalInches%12;
return *(feet)*3.49 + *(inches)*.30;
}
int *grow (int *arr, int size){
int *newArray;
newArray = new int[size*2]; //alocate new array
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i);
*(newArray + i + 1) = *(arr+i);
}
return newArray;
}
int *duplicateArray (int *array, int size) {
int *newArray;
if (size <= 0)
return NULL;
newArray = new int [size]; //allocate new array
for (int index = 0; index < size; index++){
newArray[index] = array[index]; //copy to new array
}
return newArray;
}
int *subArray( int *array, int start, int length){
int *result = duplicateArray(array,5);
return result;
}
void showArray( int *arr, int size){
for(int i = 0; i < size; i ++)
{
cout << *(arr + i) << " ";
}
}
int main(){
int size = 8;
int testArray[] = {1,2,3,4,5,6,7,8};
cout << "testing isSorted: " << endl;
cout << "test data array 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: true" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray, size);
cout << endl;
int testArray2[]= {8,7,6,5,4,3,2,1};
cout << "test data array 2: ";
showArray(testArray2, size);
cout << endl;
cout << "Expected result: false" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray2, size);
cout << endl << endl << endl;
int chainTest = 53;
cout << "Checking chain for 53 inches: " << endl;
cout << "Expected result: 15.46 " << " " << "feet: 4 " <<
" " << "inches: 5"<< endl;
int in;
int ft;
cout << "Actual results : " << chain(chainTest,&ft,&in);
cout << " " << "feet: " << ft << " " << "inches: " << in << endl;
cout << endl << endl;
cout << "testing grow: " << endl;
cout << "test data 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 " << endl;
cout << "Actual results: " << *(grow(testArray, size));
cout << endl << endl;
cout << "testing subArray:" << endl;
cout << "test data: ";
showArray(testArray, size);
cout << endl;
int start = 5;
int length = 3;
cout << "start: " << start << " " << "length: " << length << endl;
cout << "Expected result: " << "6 7 8" << endl;
cout << "Actual result: " << *(subArray(testArray, start, length));
cout << endl;
return 0;
}
Output:
As you notice, the loop is terminating after one traversal. The grow function is intended to duplicate and expand. In other words, it's supposed to make a copy of itself and append as it traverses. Any ideas as to why I am getting hung on the first element of the array?

You are actually doubling the array but only the first element is being printed because you are dereferencing an int* . To print all the elements, write a loop and print all the elements.
Also there is so much memory leak here. Please free memory after you are done using it. You are read about the delete[] operator.

Your loop going two at a time is good but it prevents you from selecting every element in the original array causing you to skip the even numbers. check your for loop and consider using two counters or if you want to modify your for loop to
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i/2);
*(newArray + i + 1) = *(arr+i/2);
}
to ensure every element is reached
also as stated in the comments, use the showArray method you implemented
showArray(grow(testArray, size),size*2);

Related

Printing values from a pointer to an array returned from a function (C++)

I have a function that returns a pointer to an array, and I want to print each value in the array
When I run it, it prints
int* merge_sort(int arr[], int size) {
if (size <= 1) {
return &arr[0];
}
int size1 = size/2;
int arr1[size1];
for (int i = 0; i < size1; i++) {
arr1[i] = arr[i];
}
int size2 = size-size1;
int arr2[size2];
for (int i = 0; i < (size2); i++) {
arr2[i] = arr[i+size1];
}
int p1 = 0;
int p2 = 0;
int sorted[size];
while (p1 < size1 && p2 < size2) {
if (arr1[p1] < arr2[p2]) {
sorted[p1+p2] = arr1[p1];
p1++;
} else {
sorted[p1+p2] = arr2[p2];
p2++;
}
}
while (p1 < size1) {
sorted[p1+p2] = arr1[p1];
p1++;
}
while (p2 < size2) {
sorted[p1+p2] = arr2[p2];
p2++;
}
cerr << "sorted: ";
for (int& i : sorted) {
cerr << i << ",";
}
cerr << endl;
return &sorted[0];
}
/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/
int main()
{
int N;
int horses[N];
cin >> N; cin.ignore();
for (int i = 0; i < N; i++) {
int Pi;
cin >> Pi; cin.ignore();
horses[i] = Pi;
}
int *sorted = merge_sort(horses, N);
cerr << "~ " << sorted[0] << " " << sorted[1] << " " << sorted[2] << endl;
//cerr << "~~ " << sorted << " " << *sorted << " " << endl;
cerr << "^ " << *(sorted + 0) << endl;
cerr << "^ " << *(sorted + 1) << endl;
cerr << "^ " << *(sorted + 2) << endl;
for (int i = 0; i < N; i++) {
//cerr << "i " << i << endl;
// cerr << "SORTED?? " << sorted[i] << endl;
cerr << "value: " << *(sorted + i) << " ";
//cerr << "*** " << *(sorted) + i << endl;
}
cerr << endl;
}
When I run it, it prints
sorted: 5,8,9,
~ 5 8 9
^ -5728
^ 942815029
^ 6297320
value: 959592096 value: 0 value: -157570874
Why is my for loop not printing the values "5, 8, 9"? How can I fix it so that it does?
(Edited to be more detailed. Also, I realize my merge sort is wrong but I'm just trying to get it to return something I can use right now ^.^)
Make sure that you returned correct pointer, for example (if pointer should point to values):
std::cerr << "\n" << sorted << " "<< &values << "\n";
should return same values:
003DFD64 003DFD64
Seems ok. Check your sort function
cpp.sh/4rrk
// Example program
#include <iostream>
#include <algorithm>
const size_t N = 3;
int* sort(int arr[]) {
// Sort arr and it should be equal to [5, 7, 8]
std::sort(arr, arr+N);
return arr;
}
int main() {
int values[N];
values[0] = 7;
values[1] = 5;
values[2] = 8;
for (size_t i = 0; i < N; ++i) {
std::cout << *(values + i) << " ";
}
std::cout << std::endl << values[0] << " " << values[1] << " " << values[2] << std::endl;
int *sorted = sort(values);
std::cout << "It is same arrays: " << values << " " << sorted << std::endl;
for (size_t i = 0; i < N; ++i) {
std::cout << *(sorted + i) << " ";
}
std::cout << std::endl << sorted[0] << " " << sorted[1] << " " << sorted[2] << std::endl;
return 0;
}
Output:
7 5 8
7 5 8
It is same arrays: 0x7329bfdc1d90 0x7329bfdc1d90
5 7 8
5 7 8

Unhandled exception at 0x012B1CA9

I am new to C++ and am trying to build a simple program that with the users input to proceed will generate a random left or right. I had the program working correctly until I added in the array to try and store each item as I have to output them as soon and the user would like to exit the loop. The program seems to compile fine but at run time I receive "Unhandled exception at 0x012B1CA9" Any help would be greatly appreciated.
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
int userSelection = 1;
const int MAX = '100';
int randNum(0);
int one (0);
int two (0);
int total(0);
int sel[MAX];
do
{
cout << "Press 1 to pick a side or 0 to quit: ";
cin >> userSelection;
for (int i = 1; i < MAX; i++)
{
srand(time(NULL));
sel[i] = 1 + (rand() % 2);
if (sel[i] == 1)
{
cout << "<<<--- Left" << endl;
one++;
total++;
}
else
{
cout << "Right --->>>" << endl;
two++;
total++;
}
}
} while (userSelection == 1);
cout << "Replaying Selections" << endl;
for (int j = 0; j < MAX; j++)
{
cout << sel[j] << endl;
}
cout << "Printing Statistics" << endl;
double total1 = ((one / total)*100);
double total2 = ((two / total)*100);
cout << "Left: " << one << "-" << "(" << total1 << "%)" << endl;
cout << "Right: " << two << "-" << "(" << total2 << "%)" << endl;
system("pause");
return 0;
};
You have a multi-character constant here... and the behavior doesn't go as expected...
Change this line
const int MAX = '100';
to
const int MAX = 100;
Note the removed single quotes.
And secondly, I will advice you to remove the Seed of the C random generator from the for loop because, you'll likely get the same values from the rand() if you always call it immediately after seeding...
But preferable use the algorithm from C++'s random header
Here is a corrected version of your original code....
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
int userSelection = 1;
const int MAX = 100; // <---changed
int randNum(0);
int one (0);
int two (0);
int total(0);
int sel[MAX];
do
{
cout << "Press 1 to pick a side or 0 to quit: ";
cin >> userSelection;
srand(time(NULL)); //< moved to here
for (int i = 0; i < MAX; i++) // <-- modified starting index
{
sel[i] = 1 + (rand() % 2);
if (sel[i] == 1)
{
cout << "<<<--- Left" << endl;
one++;
total++;
}
else
{
cout << "Right --->>>" << endl;
two++;
total++;
}
}
} while (userSelection == 1);
cout << "Replaying Selections" << endl;
for (int j = 0; j < MAX; j++)
{
cout << sel[j] << endl;
}
cout << "Printing Statistics" << endl;
double total1 = ((one / total)*100);
double total2 = ((two / total)*100);
cout << "Left: " << one << "-" << "(" << total1 << "%)" << endl;
cout << "Right: " << two << "-" << "(" << total2 << "%)" << endl;
system("pause");
return 0;
};
I think that it is basically good idea to read more about C data types and declaration. Your error:
const int MAX = '100' should be const int MAX = 100 without any quotes. C++ does implicit conversion from character literals to int.

Access Violation Violation Location With Low Numbers

I'm working on an assignment for school. The code is supposed to read form a file and create an array, then sort the values of the array to output certain info. It works just fine as long as I have 3+ lines of info in the file. If not, I get the following error:
First-chance exception at 0x01305876 in Homework11.exe: 0xC0000005: Access violation reading location 0xcd71b288.
Unhandled exception at 0x01305876 in Homework11.exe: 0xC0000005: Access violation reading location 0xcd71b288.
I can't figure out why, any help would be appreciated. Here's the code:
#include <iostream> //calls the information needed
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std; //sets all unmarked commands to std::
const int ARRSIZE = 1000;
struct Student
{
string firstName;
string lastName;
string id, temp;
double gpa;
};
int readArray(ifstream& ifile, Student arr[]);
void swapElements(Student arr[], int i, int j);
void sortArray(Student arr[], int numberInTheArray);
int main()
{ // Declares the needed variables
double sought, min, max;
int i, ival, returnvar, count = 0, mincount, maxcount;
string filename;
ifstream ifile;
Student arr[ARRSIZE];
cout << "Input File Name: ";//requesting the file name
cin >> filename;
ifile.open(filename.c_str());//opening the file
if (!ifile)//checking if it opened or not
{
cout << endl << "That file does not exist!" << endl;//informing the user it did
return 1;//not open and returning 1
}
cout << "Which number do you want to return? ";//requesting the desired number
cin >> ival;
i = ival - 1;
cout << endl;
returnvar = readArray(ifile, arr);
min = arr[0].gpa;
max = arr[0].gpa;
sought = arr[0].gpa;
while (count < returnvar)
{
if (arr[count].gpa < min)
{
min = arr[count].gpa;
mincount = count;
}
if (arr[count].gpa > max)
{
max = arr[count].gpa;
maxcount = count;
}
if (count == i)
{
sought = arr[count].gpa;
}
count++;
}
if (count == 0)
{
cout << "The file is empty!" << endl;
return 1;
}
cout << "Before Sort:" << endl;
cout << " Min GPA is " << min << " for " << arr[mincount].lastName << "." << endl;
cout << " Max GPA is " << max << " for " << arr[maxcount].lastName << "." << endl;
if (returnvar < ARRSIZE)
{
cout << " WARNING: Only " << returnvar << " numbers were read into the array!" << endl;
}
if (i >= returnvar)
{
cout << " There aren't that many numbers in the array!" << endl << endl;
}
else if (i > ARRSIZE)
{
cout << " " << i << " is bigger than " << ARRSIZE << "!" << endl << endl;
}
else if (i < returnvar)
{
cout << " Value " << ival << " is " << sought << " for " << arr[i].lastName << "." << endl << endl;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sortArray(arr, returnvar);
count = 0;
while (count < returnvar)
{
if (arr[count].gpa < min)
{
min = arr[count].gpa;
mincount = count;
}
if (arr[count].gpa > max)
{
max = arr[count].gpa;
maxcount = count;
}
if (count == i)
{
sought = arr[count].gpa;
}
count++;
}
cout << "After Sort:" << endl;
cout << " Array[0] GPA is " << min << " for " << arr[0].lastName << "." << endl;
cout << " Array[" << (returnvar - 1) << "] GPA is " << max << " for " << arr[(returnvar - 1)].lastName << "." << endl;
if (returnvar < ARRSIZE)
{
cout << " WARNING: Only " << returnvar << " numbers were read into the array!" << endl;
}
if (i >= returnvar)
{
cout << " There aren't that many numbers in the array!" << endl << endl;
}
else if (i > ARRSIZE)
{
cout << " " << i << " is bigger than " << ARRSIZE << "!" << endl << endl;
}
else if (i < returnvar)
{
cout << " Value " << ival << " is " << sought << " for " << arr[i].lastName << "." << endl << endl;
}
return 0;
}
int readArray(ifstream& ifile, Student arr[])
{
int counter = 0;
while ((ifile) && (counter <= ARRSIZE))
{
ifile >> arr[counter].firstName;
ifile >> arr[counter].lastName;
ifile >> arr[counter].id;
ifile >> arr[counter].gpa;
counter++;
}
return (counter - 1);
}
void sortArray(Student arr[], int numberInTheArray)
{
for (int i = 0 ; i < numberInTheArray - 1; i++)
{
for (int j = 0 ; j < numberInTheArray - 1; j++)
{
if ( arr[j].gpa > arr[j + 1].gpa)
{
swapElements(arr, j, j+1);
}
}
}
}
void swapElements(Student arr[], int i, int j)
{
Student temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
Please ignore the insanity and comments. Like I said, for an entry level course.
Try replacing counter <= ARRSIZE with counter < ARRSIZE (a rule of thumb in C is: never use <= in operations related to container sizes).
EDIT: also in your main(), you must check that i < ARRSIZE (equivalently, return error if i >= ARRSIZE). At present you seem to accept the case i == ARRSIZE, which is also wrong. And finally, readArray should return counter (that is, one more than the last written index).

C++ Array Error

I created a random, and its size is created randomly. Then I assign random values to this array. Finally, I want to write odd values and even values into different arrays. But the last two for loops display wrong values for evenArray and oddArray.
Where is the error? Please help me identify the error.
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
srand(time(0));
int arraySize = rand() % 10 + 4;
cout << "Array Size : " << arraySize << endl;
int myArray[arraySize];
int oddIndex = 0;
int evenIndex = 0;
int oddArray[oddIndex];
int evenArray[evenIndex];
for( int m = 0 ; m < arraySize ; m++)
{
myArray[m] = rand() % 100 + 90 ;
cout << m << "th value is : " << myArray[m] << endl;
}
for( int i = 0; i < arraySize ; i++)
{
if( myArray[i] % 2 == 0)
{
evenArray[evenIndex] = myArray[i];
cout << "EVEN ARRAY " << evenIndex << "th element is " << evenArray[evenIndex] << endl;
evenIndex++;
}
else
{
oddArray[oddIndex] = myArray[i];
cout << "ODD ARRAY " << oddIndex << "th element is " << oddArray[oddIndex] << endl;
oddIndex++;
}
}
cout << "The total number of even array elements : " << evenIndex << endl;
cout << "The total number of odd array elements : " << oddIndex << endl;
cout << "/////////////////////////////////////////\n";
cout << "EVEN VALUES" << endl;
for( int i = 0 ; i < evenIndex ; i++ )
{
cout << i << "th even value is: " << evenArray[i] << endl;
}
cout << "/////////////////////////////////////////\n";
cout << "ODD VALUES" << endl;
for( int p = 0 ; p < oddIndex ; p++ )
{
cout << p << "th odd value is : " << oddArray[p] << endl;
}
}
int oddIndex = 0;
int evenIndex = 0;
int oddArray[oddIndex];
int evenArray[evenIndex];
As you can see you are initializing oddArray and evenArray with 0 size.What you can do is declare both arrays of size arraySize,or better you can use vectors
You use wrong initialization of arrays length
int oddArray[oddIndex];
int evenArray[evenIndex];
In this lines you create two arrays of zero length. Further use to these arrays will lead to undefined behaviors.
If you need an array with dynamically changing length you should use std::vector.

"Run-Time Check Error #2 - Stack around the variable "arr" was corrupted" when I use a file with many numbers

This is supposed to read at most 1000 numbers from a file into an array and then analyze them. It works flawlessly unless I use a file with a million numbers in it. I probably because I have an infinite loop, but I can't find where. I'm not supposed to go over 1000 elements.
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
const long N=1000;
using namespace std;
//declaring the functions
int readArray(ifstream& ifile, long arr[]);
void sortArray(long arr[], int numberInTheArray);
int main()
{
//variable declaration
int n=0;
int i=0;
int numberInTheArray=0;
long minimum=0;
long maximum=0;
long arr[N]={0};
ifstream ifile;
string strVar;
cout << "Input File Name: ";
cin >> strVar;
cout << "Which number do you want to return? ";
cin >> i;
cout << endl;
ifile.open(strVar.c_str());
if(!ifile)
{
cout << "That file does not exist!" << endl;
return 1;
}
numberInTheArray = readArray(ifile,arr);
if (numberInTheArray == 0){
cout << "The file is empty!" << endl;
}
else{
maximum = arr[n];
minimum = arr[n];
n++;
while (n<=N){
if (arr[n] <= minimum){
minimum = arr[n];
}
if (arr [n] >= maximum){
maximum = arr[n];
}
n++;
}
cout << "Before Sort:\n" << " Min is {" << minimum << "}.\n" << " Max is {"
<< maximum << "}.\n";
if (i>N){
cout << " " << i << " is bigger than 1000!" << endl;
}
else if (numberInTheArray < N){
cout << " WARNING: Only " << numberInTheArray
<< " numbers were read into the array!" << endl;
if (i <= numberInTheArray){
cout << " Value " << i << " is {" << arr[i-1] << "}." << endl;
}
else {
cout << " There aren't that many numbers in the array!" << endl;
}
}
else {
cout << " Value " << i << " is {" << arr[i-1] << "}." << endl;
}
sortArray(arr,numberInTheArray);
cout << "\nAfter Sort:\n" << " Min is {" << minimum << "}.\n" << " Max is {"
<< maximum << "}.\n";
if (i>N){
cout << " " << i << " is bigger than 1000!" << endl;
}
else if (numberInTheArray < N){
cout << " WARNING: Only " << numberInTheArray
<< " numbers were read into the array!" << endl;
if (i <= numberInTheArray){
cout << " Value " << i << " is {" << arr[i-1] << "}." << endl;
}
else {
cout << " There aren't that many numbers in the array!" << endl;
}
}
else {
cout << " Value " << i << " is {" << arr[i-1] << "}." << endl;
}
}
return 0;
}
int readArray(ifstream& ifile, long arr[])
{
int n=0;
long num;
while (n<=N && ifile){
ifile >> arr[n];
n++;
}
n=n-1;
return n;
}
void sortArray(long arr[], int numberInTheArray)
{
int a;
int b;
int temp;
for (a=0; a<numberInTheArray; a++)
{
for (b=0; b<numberInTheArray; b++)
{
if (arr[a] < arr[b])
{
temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
}
}
The problem is your loop conditions n <= N. Remember that array indexes goes from zero to size minus one, so the condition should be n < N.