Segmentation fault while taking input in a 2d array in C++ - c++

The computer is giving segmentation fault whenever I try to read input into this. My input looks like:
7
1 2 3
2 3 1
1 4 4
4 6 7
7 5 2
3 5 1
4 5 5
Basically, I want to store the above input directly into a 2D array. The first column is X-coordinates, 2nd column Y-coordinate and finally the value needed to store in (X,Y) COORDINATE of a 2D array.
long leastTimeToInterview(int n, int k, int m) {
int a[m+1][m+1];
int i=0,x=0,y=0;
for (i=1;i<=m;i++){
scanf("%d %d",&x,&y);
scanf("%d",&a[x][y]);
a[y][x]=a[x][y];
}
return 11;
}

Like rustyx mentioned, this error could be a result of a stack overflow.
The easiest aproach would be to reduce the size of your array or use another data structure which allocates memory dynamically like std::vector, std::list or std::map.
In your example it also looks as if most of your array is empty. In this case i sugest using std::map.
Some other optimisations in regard of memory usage are discussed in this question: Any optimization for random access on a very big array when the value in 95% of cases is either 0 or 1?

There is no such thing as dynamically sized array in C++'s type system so you need to change it to somthing else like std::vector. The other problem is that even if your compiler supports dynamically sized arrays you still get stack overflow (at least it's very likely). So I suggest that you change your function to something like this:
long leastTimeToInterview(int n, int k, int m) {
std::vector<std::vector<int>> a(m + 1, std::vector<int>(m + 1));
int i = 0, x = 0, y = 0;
for(i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
scanf("%d", &a[x][y]);
a[y][x] = a[x][y];
}
return 11;
}
There still might be an error in the logic of your application but your example and explanation don't give enough information to tell that.

Related

vector <pair<int,int>>v(size); showing 0 as values when printed

C++: vector<pair<int,int>>v(size); showing 0 as values when I am trying to print out the values, but when the vector size is not declared it is showing correct output? Why so?
For example:
int x;
cin>>x;
vector<pair<int,int>>v(x); //Size declared.
for(int i=0;i<x;i++){
int p,q;
cin>>p>>q;
v.push_back(make_pair(p,q));
}
But when I am trying to print the values, it is printing 0 only.
I/P->
3
1 2
3 4
5 6
O/P->
0 0
0 0
0 0
But when I don't declare the size of the vector it prints the output without any error, why is that?
i.e
int x;
cin>>x;
vector<pair<int,int>>v; //Size is not declared.
for(int i=0;i<x;i++){
int p,q;
cin>>p>>q;
v.push_back(make_pair(p,q));
}
I/P->
3
1 2
3 4
5 6
O/P->
1 2
3 4
5 6
It shows the correct output. Why is that?
It is because the vector's constructor accepting an integral (it is of type size_t) does not only provide sufficient size, but creates x default objects. You then append your new objects to these default ones.
Be aware that the term 'size' in STL wording refers to the number of elements already inserted/contained, the total number of elements that can be held without re-allocation is referred to as 'capacity'.
If you want to pre-allocate sufficent capacity without creating new objects, you need to use reserve:
std::vector<std::pair<int,int>> v;
v.reserve(x);
Vector constructor with int means it create that many elements. They are pairs of zeroes. Then you push back and it creates new elements at the end. So all elements are X * 2.
I am assuming then you do not check the size, but instead you list first X elements.
You can fix by either vector::reserve(x) or by using []instead of pushing back. Then operation will look more like array access.
Because element is pair of int, both options are good.
Reserve is faster, array like access is more generic.

Memory allocation for a 2D array in c++

I'm new to c++ and trying to understand how memory allocating is done for 2D arrays.I have gone through several threads in SOF and these answers.
answer1
answer2
Those answers says that continuous memory allocation happen for 2D arrays as well like for normal arrays. (correct me if I'm wrong) Answer 2 mention that it should be able to access array[i][j] th element using*(array + (i * ROW_SIZE) + j)
But when I'm trying to do that it gives me an unexpected result.
Code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int array[2][2] = { {1, 2}, {3, 4} };
cout<<*((array+1*2) + 1)<<endl;
cout<<**((array+1*2) + 1)<<endl;
return 0;
}
Result:
0x76e1f4799008
2012576581
It doesn't give me array[i][j] th element. Can some one explain what is happening here, whether that solution is wrong or have i misunderstood the previous answers.
First you have to get a pointer to the first element of the whole thing, i.e. not just to the first row:
int *p = &array[0][0]
After that, you can index p like you want:
std::cout << *(p + 1*2 + 1) << std::endl;
The reason why your initial tries didn't work is related to types. What is happening is that in your first try you are trying to evaluate
*(array + 1*2 + 1)
Now since, array is of type "array-of-length-2" containing "array-of-length-2" containing ints, i.e. (int[2])[2] what this will do is increment array with 3 times the size of its elements, which in turn are int[2]. This will jump outside of your array. In fact *(array+3) is equivalent to array[3]. Now, that clearly is something with type int[2], which will decay to a pointer when you try to print it. In your second try, you dereference this, yielding something like array[3][0], which now is of the right type, but again, points outside of the array.
it is more like when you simulate a 2d array as a one dimensional array like this
0 1 2
3 4 5
6 7 8
and the array will be 0 1 2 3 4 5 6 7 8 to access 4 it should be *(a[0]+(1*3)+1)a[0] is the same as a(name of array).
array is 2D pointer
**array = array[0][0]
*(*array + j) = array[0][j]
*(*(array+i) + j) = array[i][j]

Incorrect output using array as counter

I'm trying to teach myself programming by attempting problems from codeabbey.com.
I'm not getting the correct output on this question.
Question:
Here is an array of length M with numbers in the range 1 ... N, where N is less than or equal to 20. You are to go through it and count how many times each number is encountered.
Input data contain M and N in the first line.
The second (rather long) line will contain M numbers separated by spaces.
Answer should contain exactly N values, separated by spaces. First should give amount of 1-s, second - amount of 2-s and so on.
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Correct Output:
5 2 3
My Output:
7 3 4
You can check here
My Code:
#include <iostream>
using namespace std;
int main()
{
int arrayLength,range,a;
cin>>arrayLength>>range;
int array[20];
array[20]={0};
for(int i=0; i<arrayLength; i++)
{
cin>>a;
++array[a-1];
}
for(a=0; a<range; a++)
{
cout<<array[a]<<" ";
}
return 0;
}
There aren't any error messages or warnings. Also, if you have any suggestions for improving the code, that'd be nice.
int array[20];
array[20]={0};
is wrong, since it leave the array un-initialized and tries to initialize the 21st element (which is undefined behaviour btw, since your array has only 20 elements, remember that indexing starts from 0). Use
int array[20] = {0}; // this will initialize all elements to 0
and your code will work as expected. See here for more details regarding aggregate initialization in C++.
array[20]={0}; initializes the 21st element(non-existing) to 0.
So you have to use int array[20] = {0}; which will initialize all 20 elements to zero.
Also from your code, you are not storing the elements to an array. You are just incrementing the corresponding count when an input is read. If so, what is the need of initializing an array to max limit. Just declare the array as you need it. In your case,
int array[range] = {0};
It will initialize an array of three (range =3 here) elements.

I don't understand how to create and use dynamic arrays in C++

Okay so I have;
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Line 4 fills the first element, how do I fill the rest?
Without line 4, line 5 reads "-842150451".
I don't understand what is going on, I'm trying to create a 2 dimensional array using x and y values specified by the user, and then fill each element one by one with numeric values also specified by the user. My above code was an attempt to try it out with a 1 dimensional array first.
The default C++ way of creating a dynamic(ally resizable) array of int is:
std::vector<int> grid;
Don't play around with unsafe pointers and manual dynamic allocation when the standard library already encapsulates this for you.
To create a vector of 5 elements, do this:
std::vector<int> grid(5);
You can then access its individual elements using []:
grid[0] = 34;
grid[1] = 42;
You can add new elements to the back:
// grid.size() is 5
grid.push_back(-42);
// grid.size() now returns 6
Consult reference docs to see all operations available on std::vector.
Should line 3 create an array with 5 elements?
Yes. It won't initialise them though, which is why you see a weird value.
Or fill the first element with the number 5?
new int(grid_x), with round brackets, would create a single object, not an array, and specify the initial value.
There's no way to allocate an array with new and initialise them with a (non-zero) value. You'll have to assign the values after allocation.
Line 4 fills the first element, how do I fill the rest?
You can use the subscript operator [] to access elements:
grid[0] = 34; // Equivalent to: *(grid) = 34
grid[1] = 42; // Equivalent to: *(grid+1) = 42
// ...
grid[4] = 77; // That's the last one: 5 elements from 0 to 4.
However, you usually don't want to juggle raw pointers like this; the burden of having to delete[] the array when you've finished with it can be difficult to fulfill. Instead, use the standard library. Here's one way to make a two-dimensional grid:
#include <vector>
std::vector<std::vector<int>> grid(grid_x, std::vector<int>(grid_y));
grid[x][y] = 42; // for any x is between 0 and grid_x-1, y between 0 and grid_y-1
Or might be more efficient to use a single contiguous array; you'll need your own little functions to access that as a two-dimenionsal grid. Something like this might be a good starting point:
template <typename T>
class Grid {
public:
Grid(size_t x, size_t y) : size_x(x), size_y(y), v(x*y) {}
T & operator()(size_t x, size_t y) {return v[y*size_x + x];}
T const & operator()(size_t x, size_t y) const {return v[y*size_x + x];}
private:
size_t size_x, size_y;
std::vector<T> v;
};
Grid grid(grid_x,grid_y);
grid(x,y) = 42;
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Create an array with 5 elements.
Line 4 fills the first element, how do I fill the rest?
grid[n] = x;
Where n is the index of the element you want to set and x is the value.
Line 3 allocates memory for 5 integers side by side in memory so that they can be accessed and modified by...
The bracket operator, x[y] is exactly equivalent to *(x+y), so you could change Line 4 to grid[0] = 34; to make it more readable (this is why grid[2] will do the same thing as 2[grid]!)
An array is simply a contiguous block of memory. Therefore it has a starting address.
int * grid;
Is the C representation of the address of an integer, you can read the * as 'pointer'. Since your array is an array of integers, the address of the first element in the array is effectively the same as the address of the array. Hence line 3
grid = new int[grid_x];
allocates enough memory (on the heap) to hold the array and places its address in the grid variable. At this point the content of that memory is whatever it was when the physical silicon was last used. Reading from uninitialised memory will result in unpredictable values, hence your observation that leaving out line 4 results in strange output.
Remember that * pointer? On line four you can read it as 'the content of the pointer' and therefore
*grid = 34;
means set the content of the memory pointed to by grid to the value 34. But line 3 gave grid the address of the first element of the array. So line 4 sets the first element of the array to be 34.
In C, arrays use a zero-based index, which means that the first element of the array is number 0 and the last is number-of-elements-in-the-array - 1. So one way of filling the array is to index each element in turn to set a value to it.
for(int index = 0; index < grid_x; index++)
{
grid[index] = 34;
}
Alternatively, you could continue to use a pointer to do the same job.
for(int* pointerToElement = grid; 0 < grid_x; grid_x-- )
{
// save 34 to the address held by the pointer
/// and post-increment the pointer to the next element.
*pointerToElement++ = 34;
}
Have fun with arrays and pointers, they consistently provide a huge range of opportunities to spend sleepless hours wondering why your code doesn't work, PC reboots, router catches fire, etc, etc.
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first
element with the number 5?
Definitely the former. With the operator "new" you are allocating memory
Line 4 fills the first element, how do I fill the rest?
Use operator [], e.g.:
for int (i=0; i < grid_x; i++) { //Reset the buffer
grid[i] = 0;
}
Without line 4, line 5 reads "-842150451".
You are just reading uninitialized memory, it could be any value.
I don't understand what is going on, I'm trying to create a 2
dimensional array using x and y values specified by the user, and then
fill each element one by one with numeric values also specified by the
user. My above code was an attempt to try it out with a 1 dimensional
array first.
Other users explained how to use vectors. If you have to set only once the size of your array, I usually prefer boost::scoped_array which takes care of deleting when the variable goes out of scope.
For a two dimensional array of size not known at compile time, you need something a little bit trickier, like a scoped_array of scoped_arrays. Creating it will require necessarily a for loop, though.
using boost::scoped_array;
int grid_x;
int grid_y;
///Reading values from user...
scoped_array<scoped_array<int> > grid(new scoped_array<int> [grid_x]);
for (int i = 0; i < grid_x; i++)
grid[i] = scoped_array<int>(new int[grid_y] );
You will be able then to access your grid elements as
grid[x][y];
Note:
It would work also taking scoped_array out of the game,
typedef int* p_int_t;
p_int_t* grid = new p_int_t [grid_x];
for (int i = 0; i < grid_x; i++)
grid[i] = new int[grid_y];
but then you would have to take care of deletion at the end of the array's life, of ALL sub arrays.

sorting gives wrong output for the element at last position

I am trying to clear some basic concepts os programming. I preferred doing sorting for this.
Below is my code:
#include<stdio.h>
#include<malloc.h>
#include <string.h>
main()
{
int array[9]={5,2,7,4,7,6,9,8,1,3};
int min,i,j,temp;
for(i=0;i<10;i++)
{
for(j=0;j<=10;j++)
{
if(array[i]<array[j])
{
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}
}
printf("\n");
for(i=0;i<10;i++)
{
printf("%d ", array[i] );
}
printf("\n");
}
And the output is :
1 2 4 5 6 7 7 8 9 9
which is unexpected. It must be
1 2 3 4 5 6 7 7 8 9
Could some one help me to know why this strange behavior at the end of the array. Why it repeats "9" and Where has "3" lost ?
Also i appreciate if some one tell me name of best sorting (Mostly i have heard of Bubble and quick sort, but why and what is the difference that i don't know). Please dont tell me about in built functions (like qsort() and etc.) because the objective is to clear concepts
You can any language to explain c/c++/ or even algorithm. Thanks
for(j=0;j<=10;j++) will give you undefined behaviour since you're accessing outside the array bounds with your subsequent array[j].
int array[9]={5,2,7,4,7,6,9,8,1,3}; is also unbalanced, you need int array[10] since you have 10 elements in your initialiser list. Better still, let the compiler do the work for you and write int array[]. This is why 3 is currently omitted from your output (notwithstanding the undefined behaviour).
array[9]; i < 10; j <= 10. array index out of bounds. undefined behaviour.
i and j should be checked like i < 9 and j < 9
int array[9]={5,2,7,4,7,6,9,8,1,3};
And you have 10 elements in that array.
You specify an array of 9 elements, and yet you have 10 elements in the initialiser and in your outer loop:
int array[9]={5,2,7,4,7,6,9,8,1,3};
// ^- this is not the last index, but the number of elements!
for(i=0;i<10;i++)
And here you iterate up to index 10, which is the 11th element (index 0 is the first):
for(j=0;j<=10;j++)
//^- when j is 10 this is still true, but there is no array[10]
To fix, change to the following:
int array[] = {5,2,7,4,7,6,9,8,1,3};
// ^- leave empty and let the compiler count the elements
const int array_len = sizeof(array) / sizeof(*array);
// length: ^- whole array / ^- one element
for (i = 0; i < array_len; ++i) {
for (j = 0; j < array_len; ++j) {
Firstly, any code should be added using the code button so that it is formatted properly and easy to read.
Secondly, you're array is too small. It's size is 9 but you have 10 items.