How to copy an entire array (not element by element) - c++

Please refer to the code (and comments) below. I am trying to make array = newArray. What is the correct syntax to do this in C++? I am trying to point array to the same memory location as newArray in memoryCopy(), thus copying newArray into array, without having to do it element-by-element as I did in deepCopy()
#include <iostream>
using namespace std;
void deepCopy(int array[], int size);
void memoryCopy(int *array, int size);
void show(int array[], int size);
int main ()
{
int array[] = {1,1,1};
show(array,3); // shows array [] = {1,1,1}
deepCopy(array, 3);
show(array,3); // shows array [] = {0,0,0}
memoryCopy(array, 3);
show(array,3); // shows array [] = {5,0,0}
// I need the above to show {5, 5, 5} ^ ^
// How can I do this in memoryCopy() using pointers?
}
void memoryCopy(int *array, int size)
{
int newArray[] = {5,5,5};
// I need to make array = newArray ...
// ... but without copying it over element by element
memcpy(array,newArray, 3); // <--???
}
void deepCopy(int array[], int size)
{
int newArray [] = {0,0,0};
for (int i = 0; i < size; i++)
array[i] = newArray[i];
}
void show(int array[], int size)
{
int i;
cout << "array [] = {";
for (i = 0; i < size-1; i++)
cout << array[i] << ",";
cout << array[i] << "}" << endl;
}

If C++ 11 or newer is available, use std::array<T,N> instead of C-Style array.
Example:
std::array<int,3> my_array {1,1,1};
auto new_array=my_array; // deep copy

Thank you all for the quick responses!
SO much help so fast, you are awesome!
Below is how it worked
void shallowCopy(int *array, int size)
{
int newArray[] = {5,5,5};
memcpy(array,newArray, 3*sizeof(int)); // <--WORKS
// thank you Manthan Tilva!
}

Related

Having trouble with my C++ program. Involes resizing an integer array dynamically

Here is what I have so far: http://cpp.sh/54vn3
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cstdlib>
using namespace std;
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE); //function prototype resize
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE); //function prototype sortFUNC
int main()
{
int SIZE = 4; //size of current array
int maxSIZE = 10; //size of final array
int *original = new int[SIZE] {5, 7, 3, 1}; //old(current) array
cout << "Elements in array: "; //test output
reSIZE(original, SIZE, maxSIZE); //call function resize
cout << endl << endl; //blank line
cout << "Elements in array in increasing order: "; //test output
sortFUNC(original, SIZE, maxSIZE); //call function sortFUNC
cout << endl << endl;
return 0;
}
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE)//function definition
{
int *temporiginal = new int[SIZE + 3]; //(final)new array
for (int i = 0; i < SIZE; i++) //copy old array to new array
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original; //delete old array
original = temporiginal; //point old array to new array
return temporiginal;
}
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE)
{
for (int i = 0; i < SIZE; i++)
{
int smallest = original[i];
int smallestINDEX = i;
for (int m = i; m < SIZE; m++)
{
if (original[m] < smallest)
{
smallest = original[m];
smallestINDEX = m;
}
}
swap(original[i], original[smallestINDEX]);
}
int *temporiginal = new int[SIZE + 3];
for (int i = 0; i < SIZE; i++)
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original;
original = temporiginal;
}
I want to add a few elements at the end of the array in main, but when I do, the program crashes when I run it. The resize function that I created is supposed to expand the function in main to hold 10 elements. The one in main originally holds 4. The new array is supposed to change that to 10. How do I add three more integers to the array in main without it crashing? Is my resize function wrong? Or is it a problem in my main? The program that is shown right now works as is. But when I add another integer in the array in main, it crashes. Like, if I add a 2 after the 1.
Thanks.
Edit: I was able to add elements at the end of the array in main by adding them in the resize function.
cpp.sh/35mww
Like mentioned earlier, maxSIZE isn't being used. There are more useless stuff as well. I have to clean this up, but I figured out what I was trying to figure out. I don't know how to use structures yet. I know that there are a lot of different ways to write a program. I'm just a beginner.
Thanks, everyone.
You need to modify the value of size everytime you call the function rezise other wise even if u call the function resize 3 times u always will have SIZE+3 on your array size.After call resize try
original[4] = 0;
original[5] = 0;
original[6] = 0;
and after that try to do this.
original[7] = 0;
you should be able to see your mistake

C++: Template argument list

I am trying to create a program that will take an original array, create one that is twice as large, and then have the original values appear twice.
I am pretty sure my code for the function is correct, but I cannot figure out what I need to put in main to make it work. I am currently getting "Expected '(' for function-style cast or type construction" and "Cannot refer to class template 'array' without a template argument list" compiler errors.
Any ideas on what I need to fix to make this work?
void repeatArray(double **array, int size)
{ //Dynamically allocate array that holds an amount of elements = size
double *resize = new double[size * 2];
for (int i = 0; i < size; i++)
{
resize[i] = (i + 1) * 2;
delete [] *array;
*array = resize;
}
}
int main()
{
const int size = 5;
**array[] = {1.1, 2.2, 3.3, 4.4};
repeatArray(double **array, size);
for (int i; i < size; i++)
{
cout << array;
}
}
You are trying to allocate a one dimensional array and make a pointer pointer point to the data that is allocated for a one dimensional array, also you are calling the wrong delete on memory allocated for a one dimensional array.
If the goal is to double the size of an array that you have allocated dynamically using new, then you can do the following
void resizeArray(int** arr, int new_size) {
delete[] (*arr);
*arr = new int[new_size];
// do your initialization here
}
int main() {
const int size = 5;
int* arr = new int[5];
resizeArray(&int, 5);
}
Although keep in mind that when you are working with dynamic arrays. It is almost always better to use std::vector than to roll your own arrays.
In C++14
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename T>
void repeatArray(std::vector<T> &array) {
int element_count = array.size();
array.resize(2*element_count);
for (int i=0; i<element_count; i++)
array[i+element_count] = array[i];
}
int main() {
vector<float> array = {1.1, 2.2, 3.3, 4.4};
repeatArray(array);
for (auto &i : array) {
cout << i << ",";
}
}

How can you print a dynamic array in C++?

Below is my current code for my latest assignment and I cannot figure out what the problem is printing the array. Forgive me for the crappy code, in my class we were thrown into C++ and none of us have ever used it before so it may be a simple mistake but no one in the house can help me.
Header file DynamicArray.h:
//
// DynamicArray.h
///#include <rpcndr.h>
#ifndef DYNAMIC_DYNAMICARRAY_H
#define DYNAMIC_DYNAMICARRAY_H
#endif //DYNAMIC_DYNAMICARRAY_H
// union
// intersection
// relative complement
// insertion - if the element is already in the set, then nothing happens
// deletion - if the element is not in the set, then nothing happens
// query to check whether an element is in a set
// query to find the number of number of elements in a set
// display the set
//destructor
// copy constructor
// ***********************************overloading assignment operator***************************************************
class DynamicArray{
public:
DynamicArray(int size);
DynamicArray(const DynamicArray &original, int Size);
/// DynamicArray(int Size);
~DynamicArray();
void Union();
void Intersection();
void Complement();
int Insert(int position, int entry, int size);
int Delete(int position, int entry, int size);
bool Qelement(int size, int entry);
int Qset(int size);
int size = 20;
int *array;
};
//
//
//
Source file DynamicA.cpp- here I define the constructors and member functions:
//
// DynamicA.cpp
//
//Union();
//Intersection();
//Complement();
//Insert();
//Delete();
//Qelement();
//Qset();
#include <iostream>
#include "DynamicArray.h"
using namespace std;
DynamicArray::DynamicArray(int &size = 30){
size = 20;
*array = new int[size];
for(int i = 0; i < size; i++){
array[i] = 0;
};
}
/// DynamicArray::DynamicArray(int Size) {
///
/// }
DynamicArray::DynamicArray(const DynamicArray &original, int size) {
size = original.size;
array = new int[size];
for (int i = 0; i < size; i++) {
array[i] = original.array[i];
}
}
DynamicArray::~DynamicArray(){
delete[] array;
}
void DynamicArray::Union(){
}
void DynamicArray::Intersection() {
}
void DynamicArray::Complement(){
}
int DynamicArray::Insert(int position, int entry, int size) {
if(!Qelement()){
for(int i = size+1; i > position+1; i--){
array[i] = array[i-1];
}
array[position] = entry;
}
}
int DynamicArray::Delete(int position, int entry, int size){
for(int i = 0; i < size; i++){
if(array[i] == entry) {
for(int x = i; x < size; i++){
array[x] = array[x+1];
}
size--;
}
}
}
bool DynamicArray::Qelement(int size, int entry) {
for(int i = 0; i < size; i++){
if(array[i] == entry){
return true;
}
}
}
int DynamicArray::Qset(int size){
return size;
}
main.cpp - this is where my issue is. The error I continue to receive is that dArray is not an array.
//main.cpp
#include <iostream>
//#include <DynamicArray.h>
#include "DynamicArray.h"
//#include "DynamicA.cpp"
//using namespace std;
int main() {
DynamicArray dArray();
for(int i = 0; i < array; i++) {
cout << dArray[i];
}
}
Your class DynamicArray is not an array, the compiler has it right. It's just a class you've defined. For your code to work, you need to overload DynamicArray::operator[](int), for example, like so:
#include <cassert>
int DynamicArray::operator[](int idx)
{
assert(idx < size);
return array[i];
}
The reason is that operator[] is only defined for the built-in array type, where it has an established meaning and understood by the compiler. But you have defined an arbitrary class, and your understanding that it is an array is only your understanding, i.e. an assumption, which in no way is perceived by the compiler, so to say.
Now, let me point this one out before you run into issues caused by that mistake: the fields size and array must be private or at least protected! Read up on encapsulation in C++, as well as the other two or three founding principles of this language. You may wonder how to access the size of the array form the outside given this change, well that's where the so-called getter-setter methods come into play. Define int DynamicArray::size() const { return size; } to let the array tell its size to its clients.
Now you can use the previously defined operator[](int) with int size():
DynamicArray myArray(5);
for(int i = 0; i < myArray.size(); ++i)
std::cout << myArray[i] << " ";
Other errors: two pointed out by#crashmstr: *array = new int[size]; should be array = new int[size]; and DynamicArray myArray(); isn't going to build, since this calls the undefined default constructor.

C++: Using dynamic memory allocation to write a function similar to the C realloc() function (i.e. change it's size)

I would like to write a function (changeSize) that uses DMA, where I can choose to change it's (an array's) size to whatever I want, where oldEls is the original size, and newEls is the new size. If newEls is larger than oldEls, I would just add zero's to the end, and if it is smaller than oldEls, I would just truncate. The "ptr" parameter needs to point to the new array. It is my understanding that this would be similar to the C realloc() function.
With the code presently below, I am outputting the following: 0, 0, 3, 6, 0, 0, 0, 0, where the correct output should be 4, 2, 3, 6, 0, 0, 0, 0. I also realize that my show function is maybe not the best function to output the new array, since I have to explicit state the array element size.
Thanks in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
void show( const int a[], unsigned elements );
int * copy( const int a[], unsigned els );
void changeSize( int * & ptr, int newEls, int oldEls );
void die(const string & msg);
int main()
{
int arr[4] = {4, 2, 3, 6};
show(arr, 4);
int * newArr = copy(arr, 4);
cout << endl << endl;
changeSize(newArr, 8, 4);
show(newArr, 8);
}
void show( const int a[], unsigned elements )
{
for (int i = 0; i < elements; i++)
cout << a[i] << endl;
}
int * copy( const int a[], unsigned els )
{
int *newArr;
try
{
newArr = new int[els];
}
catch(const bad_alloc &)
{
die("Copy: Alloc Failure");
}
for (int i = 0; i < els; i++)
newArr[i] = a[i];
return newArr;
}
void changeSize( int * & ptr, int newEls, int oldEls )
{
int * newArr;
try
{
newArr = new int[newEls];
for (int i = 0; i < oldEls; i++)
{
newArr[i] = ptr[i];
}
if (newEls > oldEls)
{
for (int k = oldEls; k < newEls; k++)
newArr[k] = 0;
}
}
catch(const bad_alloc &)
{
die("changeSize: Alloc Failure");
}
ptr = newArr;
delete[] newArr;
}
void die(const string & msg)
{
cerr << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
First of, you call delete on newArr at the end of changeSize. you need to delete the old value of ptr (that you currently discard). That's (probably) the problem
While I'm at it, I'd like to point your interest to std::vector. It's basically a resizeable array.
Also, copying raw chucks of memory is still best done with memcpy, don't waste your time with writing for loops just to copy ints, do that only for C++ classes.
EDIT: using std::copy is the best solution for C++, it uses memcpy when it can, otherwise it's the same as a for loop copying the objects.
Cheers!

C++ Splitting an array into 2 separate arrays

I need to write a program that takes a given array and then splits it into two separate arrays with one array's elements being the positive elements of the main array and the other's elements being the negative elements of the main array.
After doing my best with the code, I got about a million lines of errors when trying to compile it. Is there a problem with how I am deleting the three dynamically allocated arrays? What huge error is preventing compiling?
Here is my code:
#include <iostream>
using namespace std;
void count(int ARRAY[], int SIZE, int& NEG, int& POS);
void split(int ARRAY[], int SIZE, int& NEG_ARRAY, int NEG, int& POS_ARRAY, int POS);
void print_array(int ARRAY[], int SIZE);
int main()
{
int SIZE(0);
int* ARRAY;
cout << "Enter number of elements: ";
cin >> SIZE ;
ARRAY = new int[SIZE];
int x(0);
int numEle(0);
cout << "Enter list: " << endl;
while (numEle < SIZE)
{
ARRAY[numEle] = x;
numEle++;
cin >> x;
}
int POS(0), NEG(0);
count(ARRAY, SIZE, NEG, POS);
int* NEG_ARRAY;
NEG_ARRAY = new int[NEG];
int* POS_ARRAY;
POS_ARRAY = new int[POS];
split(ARRAY, SIZE, NEG_ARRAY, NEG, POS_ARRAY, POS);
cout << "Negative elements: " << endl;
cout << print_array(NEG_ARRAY, NEG) << endl;
cout << "Non-negative elements: " << endl;
cout << print_array(POS_ARRAY, POS) << endl;
delete [] ARRAY;
delete [] NEG_ARRAY;
delete [] POS_ARRAY;
return 0;
}
void count(int ARRAY[], int SIZE, int& NEG, int& POS)
{
for (int x=0; x < SIZE; x++)
{
if (ARRAY[x] >= 0)
{
POS = POS + 1;
}
if (ARRAY[x] < 0)
{
NEG = NEG + 1;
}
}
}
void split(int ARRAY[], int SIZE, int& NEG_ARRAY, int NEG, int& POS_ARRAY, int POS)
{
NEG = POS = 0;
for (int x = 0; x < SIZE; x++)
{
if (ARRAY[x] < 0)
{
NEG_ARRAY[NEG++] = ARRAY[x];
}
else
{
POS_ARRAY[POS++] = ARRAY[x];
}
}
}
void print_array(int ARRAY[], int SIZE)
{
for (int i = 0; i < SIZE; i++)
{
cout << ARRAY[i] << " ";
}
cout << endl;
}
The code is supposed to read in the array and display a new negative and a new positive array. Thanks in advance!
There is a bunch of errors in your code. The worst one is passing the arrays by references in the declaration and definition of the split function. Change both to void split(int ARRAY[], int SIZE, int *NEG_ARRAY, int NEG, int *POS_ARRAY, int POS);, and most of the errors will be gone.
The rest is from the two lines in which you print the array in your main:
cout<<print_array(NEG_ARRAY, NEG) <<endl;
You don't want to print the function, you want to use the function to print inside it (which you do correctly). You need to change the calls to simply:
print_array(NEG_ARRAY, NEG);
And that'll make your code compile.
Hovewer there's one more error, which will make the whole app work in an improper way. In the place you input the values, you need to get the input from cin before inputting it in the array. Like this:
while(numEle<SIZE) {
cin>>x;
ARRAY[numEle] = x ;
numEle++;
}
You have the following bugs:
void split(int ARRAY[], int SIZE, int&NEG_ARRAY, int NEG, int&POS_ARRAY, int POS);
change to :
void split(int ARRAY[], int SIZE, int*NEG_ARRAY, int NEG, int*POS_ARRAY, int POS);
also the :
void split(int ARRAY[], int SIZE, int&NEG_ARRAY, int NEG, int&POS_ARRAY, int POS){..}
change to :
void split(int ARRAY[], int SIZE, int*NEG_ARRAY, int NEG, int*POS_ARRAY, int POS){..}
and
cout<<print_array(NEG_ARRAY, NEG) <<endl
cout<<print_array(NEG_ARRAY, POS) <<endl;
to :
print_array(NEG_ARRAY, NEG);
print_array(NEG_ARRAY, POS);
After fixed these bugs, it can compile and run well.
First of all, using a std::vector is almost always nicer than using dynamically allocated C arrays. You don't get the horrible mixture of pointers and square bracket array access, and you don't need to pass round extra size variables.
Secondly, the standard library has some nice algorithms to help do what you want to do. Let's assume that you write the given numbers into a vector called vec. You can then use std::partition to move all the elements less than zero to the first half of the vector, and all the elements greater than or equal to zero to the second half, like so:
inline bool less_than_zero(int a)
{
return a < 0;
}
std::vector<int>::iterator midpoint = std::partition(vec.begin(),
vec.end(),
less_than_zero);
(There are other ways of specifying the predicate, but a simple function definition like this is easiest for demonstration purposes.)
The returned iterator points to the first item in the vector which is non-negative. So now you can easily copy the values into two new vectors:
std::vector<int> negative(vec.begin(), midpoint);
std::vector<int> positive(midpoint, vec.end());
And that's it!