How to fix this code while using dynamic 2D array - c++

I'm using dynamic 2D array and need the value of particular index but it is not printing the correct value.
```int u=5;//No. of elements
int S[u];
int i=0;
while(i<u)//elements in universal set
{
cin>>S[i];
i++;
}
int n;
cin>>n;//no. of subset
i=0;
int subcost[n];
int **subset;
subset=new int*[n];
while(i<n)
{
int l,c;
cin>>l;//size of ith subset
subset[i]=new int[l];
int j=0;
while(j<l)//Elements in each subset
{
cin>>subset[i][j];
j++;
}
cin>>c;//cost for each subset
subcost[i]=c;
i++;
}
i=0;
while(i<n)
{
int j=0;
int s=*subset[i];
while(j<s)
{
cout<<subset[i][j]<<"\n";
j++;
}
i++;
}```
I expect the output to be value of each subset, but the actual output is totally different.

arr[i]=new int[n1];
There's a misunderstanding of what new does. (Perhaps you come from Java?) This doesn't store an integer with the value of n1. It instead creates an array with a size of n1.
Just one pointer level should be enough for an array:
int n = 5;
int i = 0;
int *arr;
arr = new int[n];
arr[i] = 100;
cout << arr[i] << endl; // output: 100
delete[] arr; // remember to deallocate – otherwise memory leaks will haunt your system!
If you're looking for a 2D array, a pointer to a pointer (**) will work.
int **arr;
arr = new int[n]; //
arr[0] = new int[n]; // allocate first array
arr[0][0] = 100; // set first element of first array
delete[] arr[0];
delete[] arr; // deallocate

Here
arr[i]=new int[n1]; /* allocating memory for arr[i], equal to n1*sizeof(int) bytes & arr[i] gets points to address returned by new */
cout<<"Value of "<<i<<"th row is :- "<<arr[i]<<"\n";
I expect the output to be value of n1, but the actual output is some
random address ?
yes, arr[i] is dynamically created array & printing it will prints its base address only.
Try this version where I tried to explain code changes in comments.
int main(void) {
std::cout<<"Enter the value of n"<<"\n";
int n;
std::cin>>n;
int **arr;
/* allocate memory for arr. arr holds base address of array of n int ptr */
arr=new int*[n];
int i=0;
int n1;
std::cout<<"Enter the value of n1"<<"\n";
std::cin>>n1;
/* allocate memory for arr[0], arr[1] .. */
while(i < n1) {
arr[i]=new int[n1];
i++;
}
/* put the data into dynamically allocated array */
for(int row = 0; row < n; row++) {
for(int col = 0; col < n1; col++) {
std::cin>>arr[row][col];
}
}
/* printh te data */
for(int row = 0; row < n; row++) {
for(int col = 0; col < n1; col++) {
std::cout<<"Value of "<<i<<"th row is :- "<<arr[row][col];
}
std::cout<<"\n";
}
return 0;
}
And since you created dynamic array using new you need to free the dynamically allocated memory to avoid memory leakage, use delete operator accordingly.
As pointed by others std::vector is better option than above one.

While you have a good answer from #Achal for dynamically allocating, as mentioned, you really should use the container vector provided by C++ to make things much easier and more robust. All C++ containers provided automatic memory management freeing you from having to allocate manually (and with much less chance of getting it wrong)
When using containers, such as a vector of vectors to store your data, you can simply read and discard your "//elements in universal set", "//no. of subset" and "//Elements in each subset". Those values are not required when using containers. You simply read the value you want and add it to your container, the container will grow as needed to accommodate.
While it is not 100% clear what your input data looks like, we can deduce from your file it looks something like:
Example Input File
Where your first integers is your "//elements in universal set" which isn't needed to read the data. Likewise the second line, your "//no. of subset" is irrelevant for reading the data. Finally the 1st element on each data row, your "//Elements in each subset" is also not needed. Each of these values is simply read and discarded to arrive at your final data set.
$ cat dat/universal_sub.txt
5
4
5 1 2 3 4 5
3 1 2 3
4 1 2 3 4
6 1 2 3 4 5 6
The Final Dataset You Want To Store
From the full file, these appear to be the actual data values you want to store (there can be an even number, but there is no requirement for that)
1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6
There are many different ways you can put the pieces together. A short example of how to get your final dataset from your input file could be:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <limits>
int main (void) {
std::string line; /* string for reading each line */
std::vector<std::vector <int>> subset; /* vector<vector<int>> */
int universal, nsubsets; /* two int to read/discard */
if (!(std::cin >> universal >> nsubsets)) { /* read/dicard 2 values */
std::cerr << "error: failed to read universal.\n";
return 1;
}
/* read/discard '\n' (any chars) left in input buffer line by cin above */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
while (getline (std::cin, line)) { /* read each remaining data line */
int unneeded, i; /* 1st value and i for rest */
std::vector<int> tmp; /* vector<int> for each line */
std::stringstream ss (line); /* stringstream to read from */
if (ss >> unneeded) { /* read/discard 1st value */
while (ss >> i) /* read rest from stringstream */
tmp.push_back(i); /* add to tmp vector */
subset.push_back(tmp); /* add tmp vector to subset */
}
}
for (auto& i : subset) { /* loop over subsets */
for (auto& j : i) /* loop over each value in subset */
std::cout << " " << j; /* output value */
std::cout << '\n'; /* tidy up with newline */
}
}
(note: the output loops make use of the Range-based for loop (since C++11) but you are free to use the .begin() and .end() container functions with a traditional for loop if your compile does not support std=c++11)
Exaple Use/Output
Reading your data into a vector of vectors allows accessing each element:
$ ./bin/vector_2d_subset < dat/universal_sub.txt
1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6
Look things over and let me know if you have further questions or if I interpreted your data file format incorrectly.

Related

C++ creating an array pointing to different arrays

The inputs to this program are as follows:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
I would like n to be an array that points to other integer arrays. So, n should essentially be {{1, 5, 4}, {1, 2, 8, 9, 3}}. If I wanted to access the 0th array and the 1st index, the value should return 5, and if I were to access the 1st array and the 3rd index, the value should be 9.
However, the values that this code returns are 32764 and 32764.
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int n_l; // integer variable that will hold the length of array n
int q_l; // integer variable that will hold the length of the number of queries
cin >> n_l >> q_l; // assigns values to the variables n_l and q_l
int *n[n_l]; // creates an array that will contain pointers
for (int i = 0; i < n_l; i++){ // loops through the length of array n
int amount; // declares the variable amount
cin >> amount; // assigns a value to the variable amount
int k[amount]; // creates one of the arrays that will be added to n
for (int x= 0; x < amount; x++){ // loops through the length of k and assigns a value to each index
cin >> k[x];
}
n[i] = k; // adds the array k to the position in array n
}
for (int i = 0; i < q_l; i++){
int arraynum;
int index;
cin >> arraynum >> index;
cout << n[arraynum][index] << endl;
}
}
cin >> n_l >> q_l; // assigns values to the variables n_l and q_l
int *n[n_l];
This isn't allowed in C++. The size of an array variable must be compile time constant. You can create dynamic arrays. Most convenient way is to use std::vector class template from the standard library.
The issue with your pointers is that the automatic arrays that you create in the loop are automatically destroyed at the end of the loop statement and the pointers in the array are all dangling (i.e. invalid) pointers to destroyed arrays. When you later indirect through the invalid pointers, the behaviour of the program is undefined.
You want multiple arrays. What's a good way to create multiple objects? Array is a good way to create multiple objects. So, in order to create multiple arrays, you can create an array of arrays. Or, since you want dynamic sizes, you can create a vector of vectors. Here is an example of how to create a vector of vectors:
std::vector<std::vector<int>> n(n_l);
for(auto& vec : n) {
int amount;
std::cin >> amount;
vec.resize(amount);
for(auto& i : vec) {
cin >> i;
}
}
You could create a vector of pointers to the arrays within the vectors in the vector of vectors, but that would be pointless. You don't need the pointers.
You are defining your array inside for loop which its scope will be limited in that loop, try allocate area with new for array and save the address of newly allocated area to your pointer array.
for (int i = 0; i < n_l; i++){ // loops through the length of array n
int amount; // declares the variable amount
cin >> amount; // assigns a value to the variable amount
int *k = new int[amount];
for (int x= 0; x < amount; x++){ // loops through the length of k and assigns a value to each index
cin >> k[x];
}
n[i] = k; // adds the array k to the position in array n
}
After you’re done with it, don’t forget to delete allocated area:
for(int i = 0; i < n_l; i++)
delete[] n[i];
For starters variable length arrays are not a standard C++ feature
int *n[n_l];
Instead you could use std::vector<int *>. Or you could use std::vector<std::pair<int, int *>> where the first element of the pair stores the number of elements in the dynamically allocated array and the second element of the pair stores the pointer to the dynamically allocated array.
Moreover the array will contain invalid pointers because the arrays declared in the for loop
int k[amount];
will not be alive after exiting the for loop.
So at least you have to allocate dynamically arrays in the for loop.
And you need to check whether an entered index is a valid for a given array before accessing an element of the dynamically allocated array.

Printing out an entire array multiple times

I am wondering how you can print out an entire array multiple times in C++. Say you have the following array:
arr1 = [1,2,5,6,7,8]
and you want to print it out n times such that the output would be:
1 2 5 6 7 8
1 2 5 6 7 8
1 2 5 6 7 8
If n would be equal to 3. You could just code some number of for loops if n is a static integer, but what if it's dynamic?
I know you need to use a for loop for printing out all the contents of an array, but I'm not sure what you would do if you want to get the above output.
If n is dynamic, it doesn't matter. You can have a loop that prints the array n times quite easily:
void printInts(int* arr, size_t size) {
// some printing logic
}
int main() {
int arr[] = {0,1,2,3,4,5,6,7,8};
int n = 3; // could be anything really
for(int i = 0; i<n; i++) {
printInts(arr, 9);
}
}
The value of n doesn't really matter here: it should print n times.
If you're asking how do we know the size of arr if it's a dynamic array, that's actually pretty easy too:
Until C++11:
size_t size = sizeof(arr)/sizeof(arr[0]);
After C++11 you can use:
size_t size = *(&arr + 1) - arr;
You could do this in main() or even in printInts() if you want.
Note: keep in mind you can't get the size of a pointer allocated dynamically easily. If you allocate with say new, you'll have to keep track of the size of the array yourself.
You can't. The size of an array allocated with new[] is not stored in any way in which it can be accessed. Note that the return type of new [] is not an array - it is a pointer (pointing to the array's first element). So if you need to know a dynamic array's length, you have to store it separately.
If what you're asking is how to get user input:
int n;
cin >> n;
for (int i = 0; i < n; i++) {
// print array
}
I think you know how to use for loop.
int rows;
int arr1 [5] = {1, 2, 3, 4, 5};
cout << "Enter number of rows? ";
cin >> rows;
for(int row=1; row<=rows;row++) {
for(int index=0;index<=4;index++) {
// print the array index here and space after a digit
}
// print line-break here
}

Adding integers per line and storing it in array

I'm trying to create a mini function using dynamically allocated arrays instead of vectors because I'm trying to figure out how they work exactly.
So basically, the user enters how many number of lines they want, and then after that, they enter in a group of integers/doubles separated by a space. Then, I want the function to calculate the total sum of integers in each line, allocate it into the array.
For example:
3
1 2 3 4
3 2 2 1 //assume each line has the same # of integers (4)
1 4 4 1
Then, if I implemented my function the total of sum would then be 10, 8, 10.
So far, I have this:
int* total //is there a difference if I do int *total ??
int lines;
std::cout << "How many lines?;
std::cin >> lines;
total = new int[lines];
for (int i=0;i<lines;i++)
{
for (int j=0;j<4;j++)
{
total[i] = ? //i'm confused how you add up each line and then put it in the array, then go onto the next array..
}
}
If anything does not make sense, please feel free to ask! Thank you!
you probably will want to set total[i] to 0 right before the inner loop, and then just use operator+= to add anything you get from the std::cin stream.
// ...
total[i]=0;
for (int j=0;j<4;j++)
{
int temp;
cin >> temp;
total[i] += temp;
}
// ...
It could be a bit easier to understand if you first allocated an array to store the values and then added them together.
First of all you need to allocate an array of arrays to store numbers of each line. For example
const size_t COLS = 4;
size_t rows;
std::cout << "How many lines? ";
std::cin >> rows;
int **number = new int *[rows];
for ( size_t i = 0; i < rows; i++ )
{
number[i] = new int[COLS];
}
int *total = new int[rows];
// or int *total = new int[rows] {}; that do not use algorithm std::fill
std::fill( total, total + rows, 0 );
After that you should enter numbers and fill each row of number.
There really isn't any difference between doing int* total and int *total (in your example anyways). Personally, I prefer the second one.
As for your question, you would need to set your total to an initial value (in this case you would set it to zero) and then from there just add onto it after getting the value from cin.
With cin, since you have the spaces, it will get each individual number (as you know, I'm assuming) however you probably should (I would) store that number into another variable and then add that variable onto the total for that row.
I think that all makes sense. Hope it helps.
IMHO you can do it using a 2 dimensional array:
int** total;
// ...
total = new int*[lines];
for(int i = 0; i < lines; ++i)
{
total[i] = new int[4]; // using magic number is not good, but who cares?
for(int j = 0; j < 4; ++j)
{
int tmp;
std::cin>>tmp;
total[i][j] = tmp;
}
}
// do sth on total
for(int i = 0; i < lines; ++i)
delete[] total[i];
delete[] total;

Convert one dimensional array to two dimensional array

For my homework it is given one dimensional array and i have to convert it in a two dimensional array. The two dimensional array has 2 for the number of columns, because i have to represent the one dimensional array as pairs(the value of the number, the number of appearences in the array).
This is what have tried. The error appears on the last 2 lines of code: access violation writing location 0xfdfdfdfd.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
const int NR=17;
int arr[NR]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
int **newArr;
int count=0;
int countLines=0;
int searched;
for(int i=0;i<NR;i++)
{
newArr=new int*[countLines];
for(int i=0;i<countLines;i++)
{
newArr[i]=new int[2];
}
searched=arr[i];
if(i>0)
{
for(int k=0;k<countLines;k++)
{
if(newArr[countLines][0] == searched)
{
searched=arr[i]++;
}
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
}
else
{
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
newArr[countLines][0]=searched;
newArr[countLines][1]=count;
}
}
First you are using newArr in the first loop before allocating it any memory. You cannot dereference a pointer which owns no legal memory. It results in undefined behavior.
Secondly in the last part, you are allocating newArr a memory equal to countLines thus.
newArr = new int*[countLines] ;
It means that the indices in the first dimension of newArr are 0------>countLines-1. Doing newArr[countLines][0] = searched ; is again undefined. Make it newArr[countLines - 1].
I'm not going to bother with a line-by-line code analysis since (a) you're changing it while people are answering your question and (b) it would literally take too long. But here's a summary (non-exhaustive) of klunkers:
You are leaking memory (newArr) on each loop iteration starting with the second.
You're out-of-bounds on your array access multiple times.
You should not need to use a pointer array at all to solve this. A single array of dimension [N][2] where N is the number of unique values.
One (of countless many) way you can solve this problem is presented below:
#include <iostream>
#include <algorithm>
int main()
{
// 0. Declare array and length
int arr[]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
const size_t NR = sizeof(arr)/sizeof(arr[0]);
// 1. sort the input array
std::sort(arr, arr+NR);
/* alternaive sort. for this input size bubble-sort is
more than adequate, in case your limited to not being
allowed to use the standard library sort */
/*
for (size_t i=0;i<NR;++i)
for (size_t j=i+1;j<NR;++j)
if (arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
*/
// 2. single scan to determine distinct values
size_t unique = 1;
for (size_t i=1;i<NR;++i)
if (arr[i] != arr[i-1])
unique++;
// 3. Allocate a [unique][2] array
int (*newArr)[2] = new int[unique][2];
// 4. Walk array once more, accumulating counts
size_t j=0;
newArr[j][0] = arr[0];
newArr[j][1] = 1;
for (size_t i=1;i<NR;++i)
{
if (arr[i] != arr[i-1])
{
newArr[++j][0] = arr[i];
newArr[j][1] = 0;
}
++newArr[j][1];
}
// 5. Dump output
for (size_t i=0;i<unique;++i)
cout << newArr[i][0] << " : " << newArr[i][1] << endl;
delete [] newArr;
return EXIT_SUCCESS;
}
Output
1 : 3
2 : 1
3 : 2
4 : 3
5 : 3
6 : 3
7 : 2

reorder array starting at given position, c++

I'm new to C++ and I'm trying to do one thing that is easy in python using slice lists,
but I can't find a easy way to do that in c++.
I need to reorder a array to start at a given element like:
int array[] = {1,2,3,4,5};
reordered array to start at element 3:
{3,4,5,1,2}
this is the way I found to do that, but it seems to be a bit overkill:
void Graph::reorder(int x, MIntArray &currentArray)
{
MIntArray reorderedIndices;
int index;
for (unsigned int i=0; i<currentArray.length();i++){if(currentArray[i]==x){index=i;}} // get the index
for (unsigned int i=index; i<currentArray.length();i++){reorderedIndices.append(currentArray[i]);} // zero to index
for (unsigned int i=0; i<index;i++){reorderedIndices.append(currentArray[i]);} // index to last
for (unsigned int i=0; i<currentArray.length();i++){currentArray.set(reorderedIndices[i],i);} // transfer
}
any help would be much appreciated!!
thanks
luiz
Use std::rotate method to do this reordering. Supply the beginning of the array as the first parameter, the end of the array (i.e. array+length) as the last parameter, and the "midpoint" as the second parameter. Midpoint defines the index of the element to be moved to the initial position.
int x[] = {1,2,3,4,5};
rotate(x, x+2, x+5);
for (int i = 0 ; i != 5 ; i++)
cout << x[i] << " ";
cout << endl;
This prints 3 4 5 1 2