My problem is when I declare an array int** arr =new* int[n] and I want to assign to it pointer to array and later change that pointer to a different pointer which is copy of it values + one other number ,it brakes down and appears (probably) infinite loop . Can you say how to do this in proper way using some low tools with c++/c or can you correct my code?
Additional explenation: the code is producing very simple output but it is not important. I want to create program to change in array pointer(int*arr) in specific index pointer to diffrent pointer . But additionally pointers direct first element in arrays .Also diffrennce beetween new and old array (which is changed in int**arr in index for example 0) is that new is bigger on a new element (int this case new number).So this output is only checking if it works.
Below is my whole code
#include <iostream>
using namespace std;
void stepwise_fill_array(int ** arr, int N, int index)
{
for(int j=1;j<=10;j++)
{
int* poi=arr[index];//getting pointer to array which i wannna change
int size=0;
while(poi){poi++;size++;}//getting size of pointer array from arr
int* n= new int[size+1];//declaring the new array
for(int i=0; i<size;i++)//copying from all values from old array to new one
n[i]=poi[i];
delete[] poi;
n[size]=j;//adding to the end new value
arr[index]=n;//asigning arr[0] to new diffrent array
}
for(int i=0;i<10;i++)
cout<<arr[0][i]<<" ";
//should print 1 2 3 4 5 6 7 8 9 10
}
int main(){
int N = 10; // how big array should be and how many times it should expand
int** arr = new int*[N];//declaring our array to pointer
for(int i=0;i<N;i++)
{
arr[i]=nullptr;
}
int index =0;//index where I would change the pointer of arr
stepwise_fill_array(arr,N,index);
}
In advance thanks for your help :)
Your style of coding and explaining of problem is tragic , but fortunately I copied with it. When you are trying to get size from while(poi){poi++;size++;} you are getting in trouble. In C\C++ is no possibility to check size of array from pointer to this array. Instead you need increment size in every iteration of function stepwise_fill_array.
Below I give you correct solution(in code are leaks but I doesn't affect in much way on efficiency):
void stepwise_fill_array(int **arr, int N, int index)
{
int size = 0;
for (int j = 1; j <= 10; j++)
{
int *poi = arr[index]; //getting pointer to array which i wannna change
int *n = new int[size + 1]; //declaring the new array
for (int i = 0; i < size; i++)
{
n[i] = poi[i]; //copying from all values from old array to new one
}
n[size] = j; //adding to the end new value
arr[index] = n; //asigning arr[0] to new diffrent array
size++;
}
for (int i = 0; i < 10; i++)
cout << arr[0][i] << " ";
//should print 1 2 3 4 5 6 7 8 9 10
}
Im trying to understand pointers, below my code:
int main()
{
int size = 5; //Size of array
int position = 2; //Position to delete
int *pointer = new int[size]; //Pointer declaration
//Populates array with numbers starting at 1 up to size elements (5 in this case)
for (int i = 0 ; i < size; i++)
{
pointer[i] = i+1;
}
//Prints existing elements (numbers 1 to 5 in this case)
for (int i = 0 ; i < size; i++)
{
std::cout << pointer[i] << ", ";
}
return 0;
}
I know that if I do delete [] pointers; it will delete the array from the memory, but how can I delete just the object inside position 2 or resize the array?
You can't do either of those things. You can move items around within your existing allocation, and you can make a new allocation, copy items over, and delete the old allocation.
To work with data you should use a container called vector which provides member functions to remove an element or resize. A vector is the equivalent in C++ of what most other languages call an "array".
Here is the code for adding vertex to a graph:
void myGraph::addVertex(const string &newVertex)
{
if (getIndex(newVertex) != -1)
{
std::cout << ("addVertex: ");
std::cout << newVertex;
std::cout << (" failed -- vertex already exists.") << std::endl;
return;
}
// if array of vertices is full, we need to expand it and
// also expand Edges
if (sizeof(Vertices)/sizeof(Vertices[0])==numVertices)
{
Vertices = resize(Vertices, 2*numVertices + 1);
Edges = resize(Edges, 2*numVertices + 1);
}
Vertices[numVertices++] = newVertex;
}
and here is the code for resizing of Vertices array:
string *myGraph::resize(string array1[], int newSize)
{
// make array of size equal to new size
string *temp = new string [newSize];
int smallerSize = newSize;
// if the size of input array is less than the new size then smaller size will be that of input array
if (sizeof(array1)/sizeof(array1[0]) < smallerSize)
{
smallerSize = sizeof(array1) / sizeof(array1[0]);
}
// loop till smaller size and copy the content of input array to newly created array
for (int i = 0; i < smallerSize; i++)
{
temp[i] = array1[i];
}
return temp;
}
When I debug this code, it adds only 1 vertice, i.e. numVertices=1 and on next step it says in Vertices[numVertices++]
sizeof is giving the size of the pointer to the data in your array, not the total size of the array. It depends on your platform, but it is very likely that sizeof(string*)/sizeof(string) (equivalent to your size calculation) is always going to return 1. You should probably be using something like std::vector or std::list for this, the right choice depends on how exactly you will be using it. These standard container classes will handle allocating memory and resizing for you, so you don't have to worry about it.
You can fix it by passing old array size to resize:
string *myGraph::resize(string array1[], int array1Size, int newSize)
then:
if (array1Size < smallerSize) {
smallerSize = array1Size ;
}
as Katie explains, sizeof(array1) in your code is not the size of the actual array, you should rather use string* array1 to make clear that it is pointer to allocated memory on heap
I've been trying to figure this out off and on for a week now and I keep running into problems.
My objective:
Write a function that allocates memory for an integer array. The function takes as an argument an integer pointer, the size of the array, and newSize to be allocated. The function returns a pointer to the allocated buffer. When the function is first called, the size will be zero and a new array will be created. If the function is called when the array size is greater than zero, a new array will be created and the contents of the old array will be copied into the new array. Your instructor has provided arrayBuilder.cpp as starter code for this programming challenge. In addition, Lab9_1.exe is the executable for this application which you can test.
The code:
#include <iostream>
using namespace std;
int * arrayBuilder(int * arr, int size, int newSize);
void showArray(int * arr, int size);
int main()
{
int * theArray = 0;
int i;
cout << "This program demonstrates an array builder function." << endl << endl;
// create the initial array. The initial size is zero and the requested size is 5.
theArray = arrayBuilder(theArray, 0, 5);
// show the array before values are added
cout << "theArray after first call to builder: " << endl;
showArray(theArray, 5);
// add some values to the array
for(int i = 0; i < 5; i++)
{
theArray[i] = i + 100;
}
// show the array with added values
cout << endl << "Some values stored in the array: " << endl;
showArray(theArray, 5);
// expand the size of the array. size is not the original size. newSize
// must be greater than size.
theArray = arrayBuilder(theArray, 5, 10);
// show the new array with the new size
cout << endl << "The new array: " << endl;
showArray(theArray, 10);
cout << endl;
delete [] theArray; // be sure to do this a1t the end of your program!
system("pause");
return 0;
}
/*
FUNCTION: arrayBuilder
INPUTS Pointer to an array. Size of the array. If size is zero, arr can be NULL.
Size of the new array.
OUTPUTS: Returns a pointer to allocated memory. If newSize is greater than size,
an array of newSize is allocated and the old array is copied into the new
array. Memory pointed to by the old array is deleted. All new elements
are initialized to zero.
*/
int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
return NULL; // default return value. No memory allocated!
}
/*
FUNCTION: showArray
INPUTS: Pointer to an array. Size of the array. If size is zero, arr can be NULL.
OUTPUTS: Prints the contents of the array to the console.
*/
void showArray(int * arr, int size)
{
cout << "arr = ";
for(int i = 0; i < size; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
My struggles: I cannot figure out how to switch "arr" and a temporary array's values.
int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
int * temp = new int [newSize];
for (int i = size; i < newSize; i++)
{
*arr = *temp;
temp++;
}
return NULL; // default return value. No memory allocated!
}
another attempt while searching for answers:
int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
int * temp = new int [newSize];
memcpy (temp, arr, size *sizeof(int));
// HINT: Design the function before writing it.
delete[] arr;
for (int i = size; i < newSize; i++)
{
temp[i] = i;
}
return NULL; // default return value. No memory allocated!
}
Basically my end goal is to have the answer look like this:
This program demonstrates an array builder function.
theArray after first call to the builder:
arr = 0 0 0 0 0
some values stored in the array:
arr = 100 101 102 103 104
the new array:
arr = 100 101 102 103 104 0 0 0 0 0
PROGRESS!! Its not crashing anymore :-) This is where I'm at now:
This program demonstrates an array builder function.
theArray after first call to builder:
arr = -842150451 0 0 0 0
Some values stored in the array:
arr = 100 101 102 103 104
The new array:
arr = -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -8
42150451 -842150451 -842150451 -842150451
Press any key to continue . . .
I'll keep tinkering and let everyone know if I hit a wall! Thanks again guys!
OKAY! finally got it to display properly:
This program demonstrates an array builder function.
theArray after first call to the builder:
arr = 0 0 0 0 0
some values stored in the array:
arr = 100 101 102 103 104
the new array:
arr = 100 101 102 103 104 0 0 0 0 0
This is what I did. I feel like I may have cheated in the second part when i put 0 values in for "temp". It was my understanding that i was going to take the data from the previous array and put it into the new one, and instead I just remade it. (So it will only work with this particular set of values [only 0's]). Is there a different way I can code the second part so it works universally with whatever values are thrown at it???
int * arrayBuilder(int * arr, int size, int newSize)
{
int i = size;
int * temp = new int [newSize];
// What if the size is 0?
if (size <= 0)
{
while (i < newSize)
{
temp[i] = 0;
i++;
}
}
// Assuming the size _isn't_ 0
else
{
// "a new array will be created" (good)
for (i = 0; i < newSize; i++)
{
// The contents of the "old" array (arr) will be
// copied into the "new" array (temp)
while (i < size)
{
temp[i] = arr[i];
i++;
}
while (i >= size && i < newSize)
{
temp[i] = 0;
i++;
}
// as a hint, you can address the elements in
// both arrays using the [] operator:
// arr[i]
// temp[i]
}
}
// "The function returns a pointer to the allocated buffer."
// So, NULL is wrong, what buffer did you allocate?
return temp; // default return value. No memory allocated!
}
Since you put forth some effort.
Write a function that allocates memory for an integer array.
The prototype for this function was provided for you:
int * arrayBuilder(int * arr, int size, int newSize);
The function takes as an argument an integer pointer, the size of the
array, and newSize to be allocated. The function returns a pointer to
the allocated buffer.
This says nothing about doing anything with the "old" (passed in) array, so we should assume it needs to be left alone.
When the function is first called, the size will be zero and a new
array will be created.
The above text is meaningless given the context. Feel free to tell your instructor I said so. If the size is zero, how do you know how many elements to allocate?
If the function is called when the array size is greater than zero, a
new array will be created and the contents of the old array will be
copied into the new array.
OK, now the guts of what needs to be done (you're so close)
int * arrayBuilder(int * arr, int size, int newSize)
{
// What if the size is 0?
// Assuming the size _isn't_ 0
// "a new array will be created" (good)
int * temp = new int [newSize];
for (int i = size; i < newSize; i++)
{
// The contents of the "old" array (arr) will be
// copied into the "new" array (temp)
// as a hint, you can address the elements in
// both arrays using the [] operator:
// arr[i]
// temp[i]
// something is wrong here...
*arr = *temp;
// you definitely _don't_ want to do this
temp++;
}
// "The function returns a pointer to the allocated buffer."
// So, NULL is wrong, what buffer did you allocate?
return NULL; // default return value. No memory allocated!
}
You already got the answer here:
memcpy (temp, arr, size *sizeof(int));
but you are making several other mistakes after that. Primarily, you need to return temp ; not return NULL ;
But also you don't need the loop after the delete arr[] ;
Also don't delete arr[] if size is zero.
This is horribly complex code. Programming is all about reducing complexity.
With that in mind, here’s a proper C++ solution:
std::vector<int> arr = {1, 2, 3, 4, 5};
std::vector<int> copy = arr;
That’s it. I hope this exemplifies why you should use the standard library (or other appropriate libraries) rather than re-inventing the wheel. From the code you’ve posted I am assuming that you’ve learned (or are learning) C++ from a horrible book or course. Trash that and get a proper book. C++ is complex enough as it is, no need to add needless complexity.
Just to help you realize why the first attempt didn't work:
*arr = *temp;
This is assigning a value to the old array, from the new array. That's backwards.
But it's just targeting the first value, *arr doesn't change. You increment *temp, but you also need to increment *arr. (Also, manual pointer manipulation like that horrifying and memcopy() is a lot better. But hey, this is for learning purposes, right?)
Also, think about that loop:
for (int i = size; i < newSize; i++)
That's iterating through once for each bit that newSize is bigger than size. But you're doing two things here. 1) Copying over data and 2) initializing the new data. That for loop you have is good for going over the new data, but it's not the loop you want for copying over the data you already have. That would go from zero to size, right?
And when you're done you need to return the address of the array you built.
return NULL; // default return value. No memory allocated!
That's just some dummy mock code. It's a placeholder by the teacher. It's part of the code you're supposed to change.
Per your update:
I feel like I may have cheated in the second part when i put 0 values in for "temp"
Well what else were you going to put in there? You DO copy over the old array data. Then you EXPAND the array. What goes into the new territory? Zero values as a default is perfectly valid.
Is there a different way I can code the second part so it works universally with whatever values are thrown at it???
Well yes, but you'd have to actually have something to throw at it. Your ArrayBuilder function could take in additional arguments, possibly as a variadic function, so it knows what values to put into the new fields. But your function declaration doesn't have that. All it does is make the array bigger.
Also, in your last edit you've got those two while loops that iterate through i inside of a for loop which also iterates through i. That'll work, but just so you know it's a bit... uncouth. It's the sort of thing that'll get you in trouble when things get more complicated.
You could do this instead:
for (i = 0; i < newSize; i++)
{
if(i < size)
{
temp[i] = arr[i];
}
else // if(i >= size && i < newSize) //Wait a sec, this "if" is superfluous. It's conditions are enforced the the first if and the loop condition.
{
temp[i] = 0;
}
}
You should also probably delete the comments that make it sound like someone else wrote your code for you. Because someone else did your homework for you. It's best to
Finally, THOU SHALT INDENT THY CODE!
If I have correctly understood the assignment the function should look the following way.
First of all I would substitute the function declaration
int * arrayBuilder(int * arr, int size, int newSize);
for
int * arrayBuilder( const int *arr, size_t size, size_t newSize );
Here is its definition
int * arrayBuilder( int * arr, int size, int newSize)
{
int *tmp = 0;
if ( newSize >= 0 )
{
tmp = new int[newSize] {};
int copy_size = std::min( size, newSize );
if ( copy_size > 0 ) std::copy( arr, arr + copy_size, tmp );
}
delete []arr;
return tmp;
}
Try this:
Code:
#include <iostream>
using namespace std;
int a[3] =
{
1,
2,
3
};
int b[3];
int main ()
{
cout << endl;
cout << "Array #1 elements: " << endl;
for(int i = 0; i < 3; ++i)
{
cout << a[i] << " ";
}
for(int i = 0; i < 3; ++i)
{
b[i] = a[i];
}
cout << endl << endl;
cout << "Copying Array #1 elements to Array #2..." << endl;
cout << endl;
cout << "Array #2 elements: " << endl;
for(int i = 0; i < 3; ++i)
{
cout << b[i] << " ";
}
cout << endl << endl;
return 0;
}
I have an ordered array list. And in my resize function I create a new array and assign it the values of the old array and then I delete the old array using delete[] arrayname;.
This causes an error at run-time whenever the resize function comes into play. dbgheap.c is called. Has anyone ever seen this before?
Here is my code:
//--------------------------------------------------------------------------------------------
// Name: OrderedArray.h.
// Description: Header file for the use in OrderedArray.cpp.
//--------------------------------------------------------------------------------------------
#ifndef ORDEREDARRAY_H
#define ORDEREDARRAY_H
#include <iostream>
using namespace std;
//--------------------------------------------------------------------------------------------
// Name: template <class Datatype>
// Description:
//--------------------------------------------------------------------------------------------
template <class Datatype>
//--------------------------------------------------------------------------------------------
// Class: OrderedArray.
//--------------------------------------------------------------------------------------------
class OrderedArray
{
//--------------------------------------------------------------------------------------------
// Member Variables.
//--------------------------------------------------------------------------------------------
private:
Datatype* m_array;
int size;
int g_size;
int num_elements; //Counter for the number of elements in the Array.
void Resize(int p_size)//resizes the array to the size of p_size
{
cout << "Did i get this far ";
if(p_size < 0)//checks if new size is less than 0
{
cout << "ERROR! Size of an array can not be less than 0!" << endl;
}
else//else its ok to continue
{
Datatype* newArray = new Datatype[p_size];//creates a pointer newArray that points at a new array
if(newArray == 0)
{
return;
}
cout << "Did i get this far ";
int min;
if(p_size < size)//checks the if the new array is smaller than the old one
min = p_size;
else//else its going to be bigger
min = size;
cout << "Did i get this far ";
int index;
int temp = num_elements;//puts num_elements into a temporary variable called temp
num_elements = 0;//num_elements is set to 0
for(index = 0; index < min; index++)
{
newArray[index] = m_array[index];//places everything from the old array into the new array that will fit.
if(num_elements < temp)//if the num_elements is less than temp(the original num_elements)
{
num_elements++;//increment num_elements. This will keep incrementing to create the new num_elements based the number of elements cut off in the resize
}
}
size = p_size;//sets the old size to be equal to the new size
cout << "Did i get this far ";
if(m_array != 0)
{
cout << "\nI am just about to delete ";
delete[] m_array;//deletes the old array
}
m_array = newArray;//makes m_array point at the new array
newArray = 0;//makes newArray a null pointer
}
}
//---------------------------------------------------------------------------------------
// Name: Push
// Description:
//---------------------------------------------------------------------------------------
void push(Datatype p_item)
{
if(num_elements == size)//checks if the array is full and needs to be resized
{
Resize(size + g_size);//calls the resize function
}
int pos = num_elements;
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
{
pos=x;
}
}
//loops through the array from high to low moving all values to the right
//to make space for the passed in value until it gets to the right place
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];//moves the values to the right
}
m_array[pos] = p_item;//the passed in value is positioned into its ordered position
num_elements++;
cout<< "Num Elements " << num_elements;
cout<< "Size " <<size;
}
//--------------------------------------------------------------------------------------------
// Name: Constructor.
// Description: Constructs the Array.
//--------------------------------------------------------------------------------------------
OrderedArray(int p_size, int grow_size)
{
//Sets the Array size.
m_array = new Datatype[p_size,grow_size];
size = p_size;
g_size = grow_size;
//How many elements are in the Array.
num_elements = 0;
}
//size and g_size are given its value by the user at the start of the program.
There may be some other issue here, but the most obvious thing I can see is this:
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];
}
If pos happens to be zero, you will eventually do this:
m_array[0] = m_array[-1];
This problem will show immediately (when num_elements is zero - you haven't shown your constructor, but I do hope that you initialised everything).
Changing >= to > in the loop may solve all your troubles.
Conceptually, you ought to agree with this logic. There is no point moving the item before m_array[pos] forward to m_array[pos] when you are just about to replace it with the new item.
[edit] Now that you have posted your constructor:
m_array = new Datatype[p_size,grow_size];
This will initialise your array with the size grow_size instead of p_size, because of how the comma operator works. Read this: How does the Comma Operator work
Please do this instead:
m_array = new Datatype[p_size];
Your code m_array = new Datatype[p_size,grow_size]; in the constructor should only take one parameter which is the size of the array.
Change to this: m_array = new Datatype[p_size];