I understand how to create it in general. For example:
int ar1[3] = {1, 2, 3};
int ar2[4] = {4, 5, 6, 7};
int* ar[2] = {ar1, ar2};
cout << *(ar[1]+2);
will output:
6
Now, I would like to create the same array using cin. The format of the input is the following. The first line stores the number of arrays n. The other n lines store first the number of elements in the array, and then the elements of the arrays. For example:
2
3 1 2 3
4 4 5 6 7
To parse the input and create the array I have the following code:
int n;
cin >> n;
cout << "The number of variable-length arrays: " << n << endl;
int* ar [n];
for (int k = 0; k < n; k++){
cout << "..reading the array number: " << k + 1 << endl;
int n_el; cin >> n_el;
cout << "The array contains " << n_el << " elements." << endl;
int ar_k [n_el];
for (int j = 0; j < n_el; j++) {
cin >> ar_k[j] ;
}
ar[k] = ar_k;
for (int j = 0; j < n_el; j++) {
cout << *(ar[k] + j) << endl;
}
}
Which outputs:
The number of variable-length arrays: 2
..reading the array number: 1
The array contains 3 elements.
1
2
3
..reading the array number: 2
The array contains 4 elements.
4
5
6
7
However, if I try to access the arrays outside the loop, it does not work. Given the code:
for (int j = 0; j < 3; j++) {
cout << *(ar[0] + j) << endl;
}
the output is:
4
32766
44613906
I guess it happens because as soon as you are out of the loop, the memory where the arrays are stored gets freed. How to prevent this? Or should I use a different approach to solve the task?
You are right, the memory is getting freed when you exit the loop.
Also your code is illegal int* ar [n]; where n is a variable is not legal C++. Even though your compiler accepts it (another compiler would not).
One other approach is to use dynamic memory allocation using new. Replace
int* ar [n];
with
int** ar = new int*[n];
and
int ar_k [n_el];
with
int* ar_k = new int[n_el];
The point of dynamic allocation is that the memory doesn't get freed until you delete it.
Dynamic memory allocation is a big topic, and this answer just scratches the surface. Time for some reading.
Related
I'd like to ask you if you think about this code, whether it is totally bad or i'm doing a bad use of the memory
This is the code
// Ask for capacity
int capacity ;
cout << "capacity: ";
cin >> capacity;
// Declare the array with pointers, this line is very important
int *arr = new int;
// For 0 until capacity-1 print ask for the numbers
for (int i = 0; i < capacity; i++)
{
cout << "number: ";
cin >> *(arr + i);
}
// Print them
for (int i = 0; i < capacity; i++)
{
cout << "[" << i << "]: " << *(arr + i) << " in " << arr + i << endl;
}
And this is an example of its output
capacity: 9
number: 1
number: 2
number: 3
number: 4
number: 5
number: 6
number: 7
number: 8
number: 9
[0]: 1 in 0x55dee480c690
[1]: 2 in 0x55dee480c694
[2]: 3 in 0x55dee480c698
[3]: 4 in 0x55dee480c69c
[4]: 5 in 0x55dee480c6a0
[5]: 6 in 0x55dee480c6a4
[6]: 7 in 0x55dee480c6a8
[7]: 8 in 0x55dee480c6ac
[8]: 9 in 0x55dee480c6b0
Look that, effectively it's saving the numbers in the correct positions in memory (4 bits, the size of an int)
But what's the limit? How can I know if I'm touching memory that I shouldn't touch?
Because look that I'm declaring the array as
int *arr = new int
Is that okay?
the same with this code, but this could be a little bit worse because it's a string, an array of characters as you may know
// Declaring the pointer name as new char and ask for it
char *name = new char;
cout << "name in: ";
cin >> name;
cout << "name out\n";
for (int i = 0; *(name + i) != '\0' ; i++)
{
printf("[%i]: %c\n", i, *(name + i));
}
Example:
name in: Gilberto
name out
[0]: G
[1]: i
[2]: l
[3]: b
[4]: e
[5]: r
[6]: t
[7]: o
The code only allocates one int object. Fix:
int* arr = new int[capacity];
*(arr + i) can be simpler: arr[i].
The code needs to delete the array at the end:
delete[] arr;
Or, better, use a smart pointer to avoid having to delete manually:
std::unique_ptr<int[]> arr(new int[capacity]);
Or, even better, use std::vector<int> arr(capacity);.
Raw (owning) pointers and manual memory management is almost never a good idea in modern C++. You should use containers like std::array and std::vector rather than C-style arrays any day. And ownership and lifetime of dynamic resources is much better modeled with smart pointers like std::unique_ptr, std::shared_ptr & std::weak_ptr rather than raw pointers. Don't write code that's easy to get wrong. Use the facilities we have available, to write code that's easy to get right and hard(er) to get wrong.
I'm writing a program that gets an array of integers and its logical size. When called it creates a new array containing only the positive numbers from the arrays.
Now, in order to do this I need to write a void type function takes the following parameters:
(int* arr, int arrSize, int** outPosArrPtr, int* outPosArrSizePTR)
I'm supposed to use the pointer int** outPosArrPtr to update the base address of the array containing the positive numbers, and the pointer outPosArrSizePtr to update the array's logical size.
now when I run my code on the xcode compiler the logical size gets updated to a very larger number. So, when I tried to run the program using the online gdb compiler I got the error "Segmentation fault."
From reading what Segmentation fault means I learnt that it means that I'm trying to access memory that "does not belong to me" or memory that is not in the call stack or in the heap portion of the program.
I tried to debug my code by seeing if I was referening any null pointers or see if I was referencing any dangling pointers but it seems like the problem is another one.
My code:
#include <iostream>
typedef int* IntArrPtr;
using namespace std;
int main() {
int arrSize;
int *ptrSize;
ptrSize = &arrSize;
cout << "How many integers will this array hold:\n ";
cin >> arrSize;
IntArrPtr a;
a = new int[arrSize];
fillArr(a, arrSize);
getPosNums4(a, arrSize,&a, ptrSize);
cout << "The new size in main is: " << arrSize << endl;
cout <<"The new array with positive integers is:\n";
/*for(int i =0; i<arrSize;i++) // this runs for a large size of arrSize
cout<< a[i] << " ";
cout<<endl; */
return 0;
}
void fillArr(int a[], int size){
cout << "Please enter " << size << " Integers separated by spaces\n";
cout << "Press enter when finished >\n";
int i;
for (i=0;i<size;i++)
cin >> a[i];
}
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
IntArrPtr newArr;
newArr = new int[arrSize];
int i;
int newIndx = 0;
outPosArrSizePtr = &newIndx;//initiliaze the pointer.
for(i=0;i<arrSize;i++){
if(arr[i] > 0){
newArr[newIndx] =arr[i];
newIndx++;
}
}
arrSize = newIndx;
*outPosArrSizePtr = arrSize;
cout << "The new size is of *outPosArrSizeptr is: " << *outPosArrSizePtr << endl;
for(int j=0;j<newIndx;j++)
outPosArrPtr[j] = &newArr[j];
delete []newArr;
newArr = NULL;
for(int i=0;i<newIndx;i++)
arr[i] = *outPosArrPtr[i];
}
an example When I run this program on Xcode:
How many integers will this array hold:
6
Please enter 6 Integers separated by spaces
Press enter when finished >
3 -1 -3 0 6 4
The new size is of *outPosArrSizeptr is: 3
The new array with positive integers is:
The new size in main is: 7445512
The program ended with exit code: 0
There are quite a few problems there, but the most crucial one is that assigning a value to a function's argument has no effect on the variable whose value you passed as the argument.
It doesn't matter that the argument is a pointer – there is nothing special about pointers.
What I think is happening is that your "copy back and forth" loop (I can't understand what it's supposed to do) in the function is writing outside the input array, causing undefined behaviour and, in this case, overwriting variables in main.
You're overcomplicating your function quite a bit. It should
Create a new array
Copy the positive values to this array
Update the output parameters with the address of this array and its (logical) size
(Think of out parameters as return values and handle them last.)
Something like this:
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
int* newArr = new int[arrSize];
int newIndx = 0;
for (int i = 0; i < arrSize; i++){
if (arr[i] > 0){
newArr[newIndx] = arr[i];
newIndx++;
}
}
*outPosArrPtr = newArr;
*outPosArrSizePtr = newIndx;
}
You should also not pass pointers to your "originals" for this function to modify, you should use new variables.
int main() {
int arrSize = 0;
cout << "How many integers will this array hold:\n ";
cin >> arrSize;
int* a = new int[arrSize];
fillArr(a, arrSize);
int * positives = nullptr;
int positiveSize = 0;
getPosNums4(a, arrSize, &positives, &positiveSize);
cout << "The new size in main is: " << positiveSize << endl;
delete [] a;
delete [] positives;
}
Modern C++ uses vector rather than manually allocating arrays. Manual allocation is prone to a variety of errors that are very difficult to debug.
The logic in your getPosNums4 method appears to be the trouble. If I understand the requirement, it should look for positive integers in the input array and copy them to a newly allocated output array. Over-allocating the output array is non-optimal but not an actual bug.
void getPosNums4(int* arr, int arrSize, int** outPosArrPtr,int* outPosArrSizePtr){
IntArrPtr newArr;
newArr = new int[arrSize];
int i;
int newIndx = 0;
for(i=0;i<arrSize;i++){
if(arr[i] > 0){
newArr[newIndx] =arr[i];
newIndx++;
}
}
*outPosArrSizePtr = newIndx;
cout << "The new size is of *outPosArrSizeptr is: " << *outPosArrSizePtr << endl;
*outPosArrPtr = newArr;
}
Note the the newly allocated array will need to be delete[] by the calling function or a memory leak will result.
Here is the same program in modern C++. Note that there is no use of new/delete which saves a lot of misery.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> integer_vector;
vector<int> positive_vector;
cout << "Type in integers. Type a Q to continue:" << endl;
int an_int;
while(cin >> an_int)
integer_vector.push_back(an_int);
for_each(integer_vector.begin(),integer_vector.end(),[&](int const& n){
if(n > 0)
positive_vector.push_back(n);
});
cout <<"The new array with positive integers is:\n";
for(auto const & element:positive_vector)
cout<< element << " ";
cout<<endl;
return 0;
}
So I've been working on problem 15 from the Project Euler's website , and my solution was working great up until I decided to remove the cout statements I was using for debugging while writing the code. My solution works by generating Pascal's Triangle in a 1D array and finding the element that corresponds to the number of paths in the NxN lattice specified by the user. Here is my program:
#include <iostream>
using namespace std;
//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
void latticePascal(const int x, const int y, int &size)
{
int numRows = 0;
int sum = sumOfNaturals(x + y + 1);
numRows = x + y + 1;
//Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
unsigned long long *pascalsTriangle = new unsigned long long[sum];
size = sum;
//Initialize all elements to 0
for (int i = 0; i < sum; i++)
{
pascalsTriangle[i] = 0;
}
//Initialize top of P's T to 1
pascalsTriangle[0] = 1;
cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n"; // <--------------------------------------------------------------------------------
//Iterate once for each row of P's T that is going to be generated
for (int i = 1; i <= numRows; i++)
{
int counter = 0;
//Initialize end of current row of P's T to 1
pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
cout << "row " << i + 1 << endl; // <--------------------------------------------------------------------------------------------------------
//Iterate once for each element of current row of P's T
for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
{
//Current element of P's T is not one of the row's ending 1s
if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
{
pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <--------------------------------------------------------
counter++;
}
//Current element of P's T is one of the row's ending 1s
else
{
pascalsTriangle[j] = 1;
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <---------------------------------------------------------
}
}
cout << endl;
}
cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
delete[] pascalsTriangle;
return;
}
int main()
{
int size = 0, dim1 = 0, dim2 = 0;
cout << "Enter dimension 1 for lattice grid: ";
cin >> dim1;
cout << "Enter dimension 2 for lattice grid: ";
cin >> dim2;
latticePascal(dim1, dim2, size);
return 0;
}
The cout statements that seem to be saving my program are marked with commented arrows. It seems to work as long as any of these lines are included. If all of these statements are removed, then the program will print: "Number of SE paths in a " and then hang for a couple of seconds before terminating without printing the answer. I want this program to be as clean as possible and to simply output the answer without having to print the entire contents of the triangle, so it is not working as intended in its current state.
There's a good chance that either the expression to calculate the array index or the one to calculate the array size for allocation causes undefined behaviour, for example, a stack overflow.
Because the visibility of this undefined behaviour to you is not defined the program can work as you intended or it can do something else - which could explain why it works with one compiler but not another.
You could use a vector with vector::resize() and vector::at() instead of an array with new and [] to get some improved information in the case that the program aborts before writing or flushing all of its output due to an invalid memory access.
If the problem is due to an invalid index being used then vector::at() will raise an exception which you won't catch and many debuggers will stop when they find this pair of factors together and they'll help you to inspect the point in the program where the problem occurred and key facts like which index you were trying to access and the contents of the variables.
They'll typically show you more "stack frames" than you expect but some are internal details of how the system manages uncaught exceptions and you should expect that the debugger helps you to find the stack frame relevant to your problem evolving so you can inspect the context of that one.
Your program works well with g++ on Linux:
$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4
Number of SE paths in a 3x4 lattice: 35
There's got to be something else since your cout statements have no side effects.
Here's an idea on how to debug this: open 2 visual studio instances, one will have the version without the cout statements, and the other one will have the version with them. Simply do a step by step debug to find the first difference between them. My guess is that you will realize that the cout statements have nothing to do with the error.
I am trying to output the values present in the array, that are accepted during runtime, onto the console. But when I run this program I get the 5 values in the array as the last value only.
For example: if i give 0 1 2 3 4 as the five values for this program then the output is shown as 4 4 4 4 4.
#include "stdafx.h"
#include<iostream>
using namespace std;
int main()
{
int arrsize = 5;
int *ptr = new int[arrsize];
*ptr = 7;
cout << *ptr << endl;
cout << "enter 5 values:";
for (int i = 0; i < arrsize; i++)
{
cin >> *ptr;
cin.get();
}
cout << "the values in the array are:\n ";
for (int i = 0; i < arrsize; i++)
{
cout << *ptr << " ";
}
delete[] ptr;
cin.get();
return 0;
}
Both of your loops:
for (int i = 0; i < arrsize; i++)
...
loop over a variable i that is never used inside the loop. You are always using *ptr which refers always to the first element of the dynamically allocated array. You should use ptr[i] instead.
A part from that, dynamic allocation is an advanced topic. I'd recommend sticking with simpler and more commonly used things first:
std::cout << "Enter values:";
std::vector<int> array(std::istream_iterator<int>(std::cin), {});
std::cout << "\nThe values in the array are:\n";
std::copy(begin(array), end(array), std::ostream_iterator<int>(std::cout, " "));
Live demo
Following issues I think you could tackle:
The first include can be omitted I think. Your code works without that.
You use cin.get(), not sure why you need that. I think you can remove that. Even the one at the very end. You could put a cout << endl for the last newline. I am using Linux.
And use ptr like an array with index: ptr[i] in the loops as mentioned in the other answer. ptr[i] is equivalent to *(ptr+i). You have to offset it, otherwise you're overwriting the same value (that is why you get that result), because ptr points to the first element of the array.
P.S.: It seems that if you're using Windows (or other systems) you need the cin.get() to avoid the console to close down or so. So maybe you'd need to check it. See comments below.
everyone. I am struggling with understanding why my numbers variable keeps outputting 1. I am trying to double the size anytime the number of elements is equal to the size of the array but I end up not getting anywhere near that part of my code.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int selection;
int size = 2;
// Initializing the array
int *dArray;
int v = 0;
int i, j, temp;
dArray = new int[size];
dArray[0] = 2;
dArray[1] = 3;
int numbers = sizeof(dArray) / sizeof(dArray[0]);
do {
// Printing the menu
cout << "1) Print Elements" << endl;
cout << "2) Add Element" << endl;
cout << "3) Delete Element" << endl;
cout << "4) Return Size" << endl;
cout << "5) Exit" << endl;
cout << "Enter your selection number: ";
cin >> selection;
switch (selection)
{
case 1:
// Outputting the elements
for (int i = 0; i < size-1; i++)
{
cout << dArray[i] << ", ";
}
cout << dArray[size - 1] <<endl;
cout << numbers << endl;
break;
case 2:
// Asking for another element
cout << "What number shall be put into the array? \n";
cin >> v;
if (numbers== size)
{
// If the size is too small...
int *nArray = new int[2 * size];
for (int i = 0; i < size; ++i)
{
nArray[i] = dArray[i];
}
delete[] dArray;
dArray = nArray;
// Finished creating a new array
cout << "Array size expanded to " << 2 * size << endl;
// Adding the element
dArray[size] = v;
size = 2 * size;
// Sorting the elements
for(i=0;i<numbers;i++)
{
for(j=i+1;j<numbers;j++)
{
if(dArray[i]>dArray[j])
{
temp =dArray[i];
dArray[i]=dArray[j];
dArray[j]=temp;
}
}
}
}
else
{
// Adding the element
dArray[size] = v;
size = 2 * size;
// Sorting the elements
for(i=0;i<numbers;i++)
{
for(j=i+1;j<numbers;j++)
{
if(dArray[i]>dArray[j])
{
temp =dArray[i];
dArray[i]=dArray[j];
dArray[j]=temp;
}
}
}
}
break;
}
} while (selection!= 5);
cin.get();
cin.ignore();
return 0;
}
Does anyone know why the sizeof function keeps acting this way?
This is not the size of your array. It's the size of a pointer, divided by the size of an int.
int numbers = sizeof(dArray) / sizeof(dArray[0]);
This is the size of the array in your program.
int numbers = size;
sizeof(dArray) gives you the size of dArray. dArray is defined as int *dArray, so its size is sizeof(int*). That doesn't change, regardless of what the pointer points to. That's different from an actual array; your size code would work correctly with int dArray[3];.
To get the size of the array, just use your size variable; that's the number of int objects that were allocated.
Even better, use std::vector<int>; its size() member function tells you how many elements it has.
int numbers = sizeof(dArray) / sizeof(dArray[0]);
Numbers is resolving to 1 because dArray is a pointer to the start of your array, not the array itself. When you call sizeof() you are getting the size of the pointer, not the array. On a 32 bit application, the pointer is 32 bits (4 bytes) and your first int is also 32 bits (4 bytes). So what this statement resolves to is
int numbers = 4 / 4;
leaving 1. If you instead declared an array of doubles then sizeof(dArray[0]) would be 8 but the size of the pointer would still be 4, so the statement would resolve to numbers = 4 / 8 = .5, but since numbers is an int it would just resolve to 0. So your code would still break, but in new exciting ways.
Interestingly enough, if you compiled this as a 64 bit application sizeof(dArray) would be 64 bits (8 bytes), so you would get numbers = 8 / 4 = 2 as you expected. Then you would double your array size and your code would break because numbers would resolve to 2 which would potentially be even more confusing, so be thankful you caught it now!
I agree with what others have said though. If you use a Vector you can just keep pushing values onto the end of it and let it worry about changing the size of the array!