I am trying to create a two dimensional dynamically allocated array who's column size is increased every time the user wants to enter an additional number in the array. That is, a new address will be assigned on the heap and returned to "arr" In my example the rows are constant. The problem is I can't dynamically allocate memory and assign integers to my array to any other row besides the first.
int allocate(int** &arr, char choice)
{
int x = 1;
int index = 0;
int row = 0;
int colCount = 0;
do
{
*(arr + index) = (new int + index);
arr[row][index] = x;
//(arr[0]+index)= new int*[index]; this fundementally does not work, cant modify left value
colCount++;
cout << x << "'s address " << &arr[row][index] << " I have " << colCount
<< " columns " << endl;
x++;
index++;
cout << "Select another number?" << endl;
cin >> choice;
} while (choice != 'n');
return colCount;
}
int main()
{
int rowCount = 3;
int colCount = 0;
int **arr = new int*[rowCount];
char choice = 'n';
colCount = allocate(arr, choice);
for (int i = 0; i < colCount; i++)
{
delete[] arr[i];
}
delete[] arr;
return 0;
}
My problem is with this line of code here
*(arr + index) = (new int + index);
while it does print out the values and addresses I allocated assigned in my function, I get a heap corruption when I try to delete the memory I assigned .Also, I can't figure out how to get the numbers to assign
Also, if I am not mistaken *(arr + index) is giving me pointers of the first column only! So I am not even sure why this is working!
Why don't you use vector<vector<int>>? Vector is a dynamic array.
I have no idea what the line *(arr + index) = (new int + index); even supposed to do.
If you want to allocate array of ints size columnSize you write it as:
int * column = new int[columnSize]
If you want to store the pointer in arr at location index then write
arr[index] = new int[columnSize]
I am not sure what you wanted to write, your code is confusing for me. Why don't you use std::vector<int>? Or std::vector<std::vector<int> >?
Related
For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.
I am a getting a segment fault when trying to input data for my array of pointers. Im pretty new to coding so any help would be great. My task was to make an array of pointers then display, swap them around and than sort them
#include <iostream>
using namespace std;
float getValueFromPointer(float* thePointer)
{
return *thePointer;
}
float* getMinValue(float* a, float* b)
{
if (*a < *b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int arraySize;
cout << "Enter the array size: ";
cin >> arraySize;
float** speed = new float*[arraySize]; // dynamically allocated array
for(int i = 0; i < arraySize; i++)
{
cout << "Enter a float value: ";
cin >> *speed[i];
}
// Core Requirement 2
for (int i = 0; i < arraySize; i++)
{
float value = getValueFromPointer(*speed+i);
cout << "The value of the element " << i << " is: ";
cout << value << endl;
}
//float *pointerToMin = getMinValue(&speed[0], &speed[arraySize - 1]);
//cout << *pointerToMin << endl;
delete [] speed;
speed = NULL;
return 0;
}
You’ve only allocated space for the outer array but you need to also allocate space for each of the internal floats.
So before calling this line:
cin >> *speed[i];
You need to first allocate space for it:
speed[i] = new float;
Your problem is that you've allocated an array of float pointers. You need to allocate an array of floats. So currently you have no memory allocated for the actual floats. If you do this, you'll allocate that memory:
float *speed = new float[arraySize];
You don't have any need for a 2D/jagged array that I can see. If you start with the code above, the compiler errors should lead you right in the direction. (Basically you will start removing * from a lot of places in your code.)
EDIT
Based on your requirement that I misunderstood, a possible approach is the following. The other answer (the one that isn't mine) makes sense in broader scenarios than this, but hopefully this is sort of another angle to think about that rather arbitrary problem you're trying to solve:
int main()
{
float *pFloats = new float[10];
float **ppFloats = new float*[10];
//assign float values and pointers to them in same loop
for (int i = 0; i < 10; i++)
{
pFloats[i] = i;
ppFloats[i] = &pFloats[i];
}
//swap two arbitrary pointers
float *pTemp = ppFloats[4];
ppFloats[4] = ppFloats[5];
ppFloats[5] = pTemp;
//print our float array
for (int i = 0; i < 10; i++)
printf("%f\n", pFloats[i]);
//print our float array *through* our pointers
for (int i = 0; i < 10; i++)
printf("%f\n", *ppFloats[i]);
delete[] ppFloats;
delete[] pFloats;
}
Ignore the hard-coded constants, etc...The point here is that I've created a contiguous memory area for the floats, and then created an array of float pointers on top of it. Note that I can sort my pointer array with zero impact on the original array. There are much smarter ways to do this, but...looks like you're learning about raw pointers, so...
Contrast with the other answer which creates jagged memory for the floats (1 at a time, on demand, not necessarily contiguous).
I've got something like this:
static int n = 0; // global static int
int *arr = new int[n]; // global int*
int randToArray(int arr[], int min, int max) {
srand(time(NULL));
for(int i = 0; i <= n; i++) {
arr[i] = (rand() % max + min);
}
}
void printArray() {
if(n) {
for(int i = 0; i < n; i++)
cout << arr[i] << endl;
} else
cout << "The array hasn't been drawed yet.";
}
And then in the main function I have a menu with a switch and options for getting random numbers and printing the array:
switch(option) {
case 1:
cout << "Set the size of the array: ";
cin >> n;
randToArray(arr, 1, 99);
break;
case 2:
printArray();
wait();
break;
}
I need my array to be available globally in order to use in several other functions.
Everything works except one thing: when I want to print the array I get working properly only 8 first elements. Then the terminal shows up some very large numbers.
That's because you use
static int n = 0;
then allocate memory for zero elements.
Change the line static int n = 256; for example, to allocate memory for 256 elements.
Or, if you read n after, allocate the memory AFTER you have read n. That is, declare the array globally first (technically a pointer), as int *arr;, then
arr = new int[n];
after cin >> n;
static is a much overloaded keyword.
The way you use it, it means translation-unit-local.
Also, you don't have any global array in your code, only a pointer initialized to point to the beginning of an allocation of 0 ints.
That allocation won't be changed if you later change n.
I'm currently making a code on the MU game using dynamic arrays, and I've got a problem with printing a sequence.
Rule: If the first character is denoted by the character M, and the rest of the sequence is denoted by R, then the new sequence is MRR.
Examples include:
Current sequence: MIUI
New sequence: MIUIIUI
Current sequence: MUM
New sequence: MUMUM
Current sequence: MU
New sequence: MUU
Here are snippets of my code:
IN MAIN:
if (userchoice == 2)
{
if (rule2valid == false)
{
cout << "This rule may not be applied to your input." << endl;
return 0;
}
int newsize = size + size - 1;
char *resultant = new char[newsize];
resultant = applyRule2(userinput, size);
printarray (resultant, newsize);
}
In the function which applies the rule:
char *applyRule2(char* sequence, int size)
{
int newsize = size + size - 1;
int j = 1;
char* applyRule = new char[newsize];
for (int i = 0; i < size; i++)
applyRule[i] = sequence[i];
for (int i = size; i < newsize; i++)
{
applyRule[i] == sequence[j];
}
return applyRule;
}
and the function for printing:
void printarray(char* sequence, int size)
{
for (int i = 0; i < size; i++){
cout << sequence[i] << "\t";
}
cout << "The length of this array is : " << size;
cout << endl;
}
The problem is that when I run the program, my output is as such:
Input: M U M
Output: M U M, The length of this string is 5. (supposed to be M U M U M)
Input: M I U I
Output: M I U I, the length of this string is 7. (supposed to be M I U I I U I)
What I have done so far is that I allocated a new dynamic array with the new size, and added values into the array accordingly. I am, however, at a loss as to whether the problem lies in the applyRule2 function or in the printarray function.
It would be greatly appreciated if someone could point me out in the right direction.
There are a few error in your code. As Alf says you really should use std::string. but anyway here are some of the errors.
for (int i = size; i < newsize; i++)
{
applyRule[i] == sequence[j];
}
should be
for (int i = size; i < newsize; i++)
{
applyRule[i] = sequence[j];
}
You had a double equals == when you should have written one equals =. Your compiler should have warned you about this, pay attention to compiler warnings.
Another error
char *resultant = new char[newsize];
resultant = applyRule2(userinput, size);
should be
char *resultant = applyRule2(userinput, size);
The code you have written allocates some memory and then on the very next line it throws away that memory and instead uses the memory you allocated in applyRule2. So this isn't actually a bug, but it is a waste of resources. Your program will never get back the wasted memory. This is called a memory leak.
just use std::string instead of raw arrays and raw pointers and new
A few days ago I learned about creating 2D allocated memory arrays from the internet, it works perfect. To access the array we just simply use matrix[i][j], however is there any way that I can dereference this 2D array by using * notation instead of [] for input as well as other methods?
First questions is solved I can use *(*(matrix + i) + j)
Now I got another question, last code segment is to free the allocated memory (I got it from internet as well), but I don't understand it, why cant I just use delete [] matrix ?
int **matrix;
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
{
matrix[count] = new int[col];
}
// input element for matrix
cout << endl << "Now enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << endl << "Row " << (i+1) << " Col " << (j+1) << " :";
cin >> matrix[i][j]; // is there any equivalent declaration here?
}
}
// free dynamically allocated memory
for( int i = 0 ; i < *row ; i++ )
{
delete [] matrix[i] ;
}
delete [] matrix ;
Answering your second question: when you allocate a 2D array with the following code
// dynamically allocate an array
matrix = new int *[row];
for (int count = 0; count < row; count++)
matrix[count] = new int[col];
you are in fact allocating one array of pointers (your matrix variable, which is a double pointer) and "row" arrays of integers (each one representing one row in your matrix, of size "col"), which are matrix[0], matrix[1], etc. up to matrix[row-1].
Thus, when you want to free your matrix, you'll first need to free every single row (the arrays allocated within the loop), and then the array which held the rows. In your case, the code you use to free your matrix is partly wrong, and should be more like the following :
// free dynamically allocated memory
for( int i = 0 ; i < row ; i++ )
{
//first we delete each row
delete [] matrix[i] ;
}
//finally, we delete the array of pointers
delete [] matrix ;
The delete within the loop will free each row of your matrix, and the final delete will free the array of rows. In your code, you use delete row times on your double pointer (matrix), which makes no sense.
Finally, using a single delete on the double pointer is wrong, because it would end up in a memory leak as you aren't freeing the memory allocated for each row, only the pointers referring to it.
Since a[b] is just *(a + b) you can of course do this:
*(*(matrix + i) + j)
Anyway, those new allocations are error prone. If one of the nested news throws then you'll have a leak. Try using std::vector instead.
Something like this would work:
int **matrix;
// dynamically allocate an array
matrix = new (std::nothrow) int *[row];
if (matrix == NULL)
{
// handle the error
}
for (int count = 0; count < row; count++)
{
*(matrix + count) = new (std::nothrow) int[col];
if (matrix[count] == NULL)
{
// handle the error
}
}
cout << "\nNow enter the element for the matrix...";
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
cout << "\nRow " << (i+1) << " Col " << (j+1) << " :";
cin >> *(*(matrix + i) + j);
}
}
Yes, you use pointer addition, but you need to understand how the memory is laid out. Say x is a pointer to the first element of an array of ints, if you want to access x[2], you can use *(x+2). However, with matrices it can get quite confusing and you're a lot more likely to access wrong indices in your matrix if you do this, so I wouldn't advise it.
You could do *(*(matrix+i)+j). It should be equivalent to bracket notation. What is happening with both notations is simply pointer arithmetic.