vector push_back memory access denied in Visual Studio - c++

#include <stdio.h>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers;
numbers.resize(10001);
for (int i = 0; i < 10000; i++)
{
numbers.push_back(1);
}
return 0;
}
If I put more than 5000 1s in the vector, I get the following error, I don't understand.
There is no doubt about it other than the memory overflow. But int type = 4 bytes, so 4byte * 10000 = 40000byte 0.04mb
Why am I getting an error?

The error seems unrelated to the code that you've shown.
Now, looking at your code there is no need to use resize and then using push_back as you can directly create a vector of size 10001 with elements initialized to 1 as shown below:
std::vector<int> numbers(10001,1);// create vector of size 10001 with elements initialized to 1
Or you can used std::vector::reserve instead of std::vector::resize, though this is totally unnecessary as you can use the first method shown above.
vector<int> numbers;
numbers.reserve(10001); //use reserve instead of resize
for (int i = 0; i < 10000; i++)
{
numbers.push_back(1);
}

Related

Using vectors in C++ program is not printing anything

I have written a C++ program to find fibonacci numbers. It's running successfully but is not printing anything.
#include<bits/stdc++.h>
using namespace std;
int main(){
int n = 5;
vector<int> fib;
fib[0] = 0;
fib[1] = 1;
for (int i = 2; i <= n; i++){
fib[i] = fib[i-1] + fib[i-2];
}
cout<<fib[n];
}
If I do the same thing using array instead of vector it prints successfully.
#include<bits/stdc++.h>
using namespace std;
int main(){
int n = 5;
int fib[10];
fib[0] = 0;
fib[1] = 1;
for (int i = 2; i <= n; i++){
fib[i] = fib[i-1] + fib[i-2];
}
cout<<fib[n];
}
I have tested this on sublime text and onlinegdb.
int fib[10];
This creates an array of 10 integers.
vector<int> fib;
This creates a vector of size 0, with 0 integers.
For these two snippets to match, you need to initialize the vector with 10 integers like the array. So:
vector<int> fib(10);
Some notes on vectors
One of the big differences between std::vector and primitive arrays is that std::vector is resizable! So while initializing the vector with 10 ints like above will work, you could also add them on the fly using push_back() or by calling resize().
Likewise, std::vector has a .at() function for access. It's marginally slower than the subscript operator ([]), so I would not suggest using it in production-level code. But while you're learning, I would strongly suggest using .at(), as it will do bounds checking for you. So this program would've told you you were trying to access locations in the vector that don't exist--instead of just running with Undefined Behavior.
Note that when you wrote :
vector<int> fib;//creates an empty vector that is a vector of size 0
fib[0] = 0; //UNDEFINED BEHAVIOR
fib[1] = 1; //UNDEFINED BEHAVIOR
In the above code snippet, you created an empty std::vector. That is a vector of size 0.
Next when you wrote fib[0] = 0; you're trying access the first element of the vector. That is, the element at index 0. But note that there is no element inside the vector and so you have undefined behavior in your program.
Similarly when you wrote fib[1] = 1;, you're trying to access the second element of the vector. But since there is no element inside the vector, this again leads to undefined behavior.
To solve this you can create a vector of some size(say 10) and then access its elements as shown below:
vector<int> fib(10);//create vector of size 10
fib[0] = 0;//OK NOW
fib[1] = 1;//OK NOW
Since you're using indices to access the elements of the vector, i have not suggested push_back. std::vector::push_back is a member function that can be used to add an element into the vector.

C++ Array of Array Products :exited, segmentation fault

I am a newbie in cpp field.
Below is my cpp code. When I use the online c++ compiler, and
why does it happened to exited, segmentation fault, and what's wrong with my code.
Thanks guys.
Problem description:
Given an array of integers arr, you’re asked to calculate for each index i the product of all integers except the integer at that index (i.e. except arr[i]). Implement a function arrayOfArrayProducts that takes an array of integers and returns an array of the products.
Solve without using division and analyze your solution’s time and space complexities.
#include <iostream>
#include <vector>
using namespace std;
vector<long> arrayOfArrayProducts(const vector<int>& arr)
{
vector<long> res = {};
int n = arr.size();
// handles edge cases as well
if(n==0 || n==1){
return res;
}
int product;
// your code goes here
for(int i=0; i<n; i++){
product = 1;
for(int j=0; j<n; j++){
if(i!=j){
product = arr[j]*product;
}
res[i]=product;
}
}
return res;
}
int main() {
// vector initiallize
//vector<int> arr{8, 10, 2};
const vector<int> arr;
int n = arr.size();
vector<long> ans(n,0);
ans = arrayOfArrayProducts(arr);
for(int i=0; i<n; i++){
cout<< ans[i] <<' ';
}
return 0;
}
Here is the line where the failure comes:
res[i] = product;
and the reason is because you declared res like this:
vector<long> res = {};
so you are trying to access the long element located at 'cell' i of an empty vector... that is not allowed in C++ and the result is undefined behavior
fix it:
the same way as in the main function
std::vector<long> arrayOfArrayProducts(const std::vector<int>& arr)
{
int n = arr.size();
std::vector<long> res(n, 0);
....
Segmentation faults typically occur when you try to read past the bounds of an array. This fault in your code means that you're trying to read/ write something from an array which is not allocated. If you take a closer look, res[i]=product means that your accessing elements from the vector res. But you haven't reallocated or inserted data into it. This is the reason for the segmentation fault.
To resolve this, resize the res vector to the size of arr so that the vector will have the elements in memory to be accessed,
vector<long> arrayOfArrayProducts(const vector<int>& arr)
{
vector<long> res(srr.size());
...
You are getting this error because you are trying to access the index i of the vector<int> res that you never initialized. on this line:
res[i] = product;
For that you have to understand how Vector works, Vector is dynamic container which can shrink and expand based on its usage, in your case, You Initialized it with default constructor, which did not allocated any memory to hold int. So when you try to access that you get undefined behavior.
In case of default construction of vector. You cannot assign to a particular index. but you have can put data in it via this:
res.push_back(data);
You can fix it by using these constructors:
std::vector<int> res(arr.size(), 0); // In second parameter you can pass default values for all the elements in the vector.
std::vector<int> res(arr.size()); //This will simply initialize elements with default constructor

What is the recommended way loop through an array in C++?

I'm learning C++ (reasonably confident in JavaScript) and I can't find a C++ equivalent to the JS array.length;. I want a simple way to loop through an array based on the array length?
I have followed a number of tutorials but all seam to require the array length to be manually stated in the for loop (or pushed into the function)?
Below code gets an error and adding the #include causes a compiler error (DEV++).
Is there a C++ or reason why there is no simple call of the array length?
#include <iostream>
using namespace std;
int main () {
int shoppingList [3] = {1, 2, 3};
for (int i=0; i < shoppingList.size(); i++) {
cout << shoppingList[i] << endl;
}
}
For a C-style array like you have you can use range-based for loops:
for (int value : shoppingList)
{
std::cout << value << '\n';
}
As for getting the number of elements from an array, there's a "trick": You know the size of the array itself, and you know the size of each element in the array. That means if you divide the size of the array with the size of each element, you will get the number of elements.
In short
size_t numberElements = sizeof shoppingList / sizeof shoppingList[0];
Important note: This "trick" only works with actual arrays! Once an array have decayed to a pointer (to its first element, which often happens) all you're left with is the pointer. There's no way to get the size of the memory it points to, and this "trick" can not be used.
And as mentioned in my comment, the "best" solution is to use either std::array or std::vector.
Built-in types don’t have member functions with C++. However, there is a non-member std::size(array) function:
for (std::size_t i{}; i != std::size(shoppingList); ++i) {
// ...
}
Note that the counter is usinf std::size_t to match the signedness of the result of std::size(...). Also, do not use the sizeof hack suggested in other answers: it is a trap! The cde will happily compile when passing pointers to it but it will also produce the wrong result.
Of course, the idiomatic way to iterate over a range in C++, including arrays, is (assuming you only need the values and not their position):
for (int val: shoppingList) {
// ...
}
Array doesn't have a direct size() member function, you can find the size of an array like this int size = sizeof(arr)/sizeof(arr[0]); and use it in the for loop.
#include <iostream>
using namespace std;
int main () {
int shoppingList [3] = {1, 2, 3};
int size = sizeof(shoppingList)/sizeof(shoppingList[0]);
for (int i=0; i < size(); i++) {
cout << shoppingList[i] << endl;
}
}
You can do something like, sizeof(A)/sizeof(A[0]). This would give you the total number of elements in the array.
Let's take an example A = {1,2,3,4,5} // all ints
If you evaluate sizeof(A)/sizeof(A[0]), it would give you 5 and as you see, you would not need to manually enter the size of the array.
Hope this helps. :)
#include <iostream>
using namespace std;
int main()
{
A = {1,2,3,4,5};
for (int i = 0; i< sizeof(A)/sizeof(A[0]); i++)
//whatever you want to do with this
return 1;
}

generating and storing random arrays in c++

I am working on a program which takes the initial array as an input and then randomly generates 10 random arrays from the initial array.
I have written a function to generate a single random array from the initial array.
However,I am unable to develop a code which calls this function in the main function and generates 10 such random arrays.I will also be using these 10 randomly generated arrays for further calculation in the main function.
Since my knowledge of C++ is limited for now,I am not aware of using vectors for dynamic allocation.It would be of great help if anyone can guide be regarding the code to be used in the main function.
Here int initial[] is the first array used to generate 10 other random arrays using the int *newparents() function. When the newparents() function is called in main it returns one randomly shuffled array.
I would request your help in generating 10 random arrays in the main function by calling the newparents() function and then storing them for further use.
Code :
int initial[] =
{ 10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200 };
int size = sizeof(initial) / sizeof(initial[0]);
int *newparents()
{
int *pt = new int[size];
random_shuffle(&initial[0], &initial[size]);
for (unsigned i = 0; i<size; i++)
{
pt[i] = initial[i];
}
return pt;
}
int main()
{
int *p;
p = newparents();
cout << "p1=" << " ";
for (int i = 0; i<size; i++)
{
cout << *(p + i) << " ";
}
return 0;
}
Thank you for your help.
A simple way to do this using std::vector :
#include <iostream>
#include <vector>
#include <algorithm>
std::vector< std::vector<int> >
GenerateRandomArrays( std::vector<int> const & inInitialArray, int inNumberOfArrays)
{
std::vector<std::vector<int> > generatedArrays;
std::vector<int> tempArray(inInitialArray);
for (int i = 0; i < inNumberOfArrays; i++)
{
std::random_shuffle(tempArray.begin(), tempArray.end());
generatedArrays.push_back(tempArray);
}
return generatedArrays;
}
int main() {
// Creates the initial array.
std::vector<int> initial{ 10,20,30,40,50 };
auto blah = GenerateRandomArrays(initial, 10);
return 0;
}
Output :
50 20 40 30 10
50 40 30 10 20
20 10 30 50 40
30 40 20 10 50
30 50 20 10 40
20 50 10 40 30
50 30 20 10 40
30 40 20 10 50
20 10 50 40 30
20 50 10 40 30
Note : I am creating a new tempArray only because I think you do not want to alter the intial vector. If that is not a case for you then, you can just shuffle the initial array itself and add it to the vector of vectors.
To create array of 10 pointers to the shuffled arrays using your code you can simply:
int *arr[10];
for (int i = 0; i < 10; ++i)
arr[i] = newparents();
int *arr[10]; will create array of 10 pointers to int, which is what what your newparents(); function returns, a pointer to the first int of shuffled array.
Since you allocated those arrays on the heap, make sure you free that memory once finished with them:
for (int i = 0; i < 10; ++i)
delete[] arr[i];
I have written a function to generate a single random array from the initial array.
No, you wrote a function to shuffle the initial array in place and then copy it. This is frankly a bit odd, because I don't see why you want to mutate the global in-place (after the first time you call your function, the global array is still called "initial" but is no longer in its initial state).
Since my knowledge of C++ is limited for now,I am not aware of using vectors for dynamic allocation.
The whole point is that std::vector handles all the allocation for you, avoiding the memory leaks and manual copying in your current code.
If you take the time to use C++ properly, instead of trying to write C in C++, the code is pretty trivial:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
// let's avoid mutating our global state
const std::vector<int> Seeds =
{10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200};
// this shuffles a copy of the argument passed
std::vector<int> shuffle(std::vector<int> v) {
std::random_shuffle(begin(v), end(v));
return v;
}
// return n independently-shuffled copies of "initial"
std::vector<std::vector<int>> shuffle_n(size_t n,
std::vector<int> const& initial) {
std::vector<std::vector<int>> result(n);
std::generate_n(begin(result), n,
[&initial]() {
return shuffle(initial);
});
return result;
}
int main() {
// one line to create 10 shuffled vectors
auto allparents = shuffle_n(10, Seeds);
// and one loop to print them all
for (auto &v : allparents) {
std::cout << '{';
std::copy(begin(v), end(v),
std::ostream_iterator<int>(std::cout, " "));
std::cout << "}\n";
}
}

Creating a two-dimensional vector from a file?

I'm trying to read data from a grid, in a 20x20 file. I'm using a two-dimensional vector of vectors of strings.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
#define HEIGHT 20
#define WIDTH 20
typedef vector<vector<string> > stringGrid;
bool readGrid(stringGrid& grid, string filename) {
grid.resize(HEIGHT);
for (int i = 0; i < HEIGHT; i++)
grid[i].resize(WIDTH);
ifstream file;
string line;
file.open(filename.c_str());
if (!file.is_open()) {
return false;
}
for (int i = 0; i < HEIGHT; i++)
{
while (getline(file, line)) {
grid[i].push_back(line);
}
}
return true;
}
void displayGrid(stringGrid grid)
{
for (int row = 0; row < HEIGHT; row++)
{
for (int col = 0; col < WIDTH; col++)
{
cout << grid[col][row];
}
cout << endl;
}
}
int main(){
stringGrid grid;
readGrid(grid, "test.txt");
displayGrid(grid);
return 0;
}
However, when I run this code, the program only outputs a few blank lines.
Why doesn't this code work? The logic seems sound enough.
You can do what Kocik said or you could use vector::reserve instead of vector::resize in your code. It should then work.
reserve simply reserves enough memory to avoid reallocating memory while it's pushing back items.
resize actually resizes the vector by adding n default items. In your case, those items are empty vectors of strings, so you'll get 20 of them in your vector before any other items you subsequently push back.
Here is a bit more info about the difference between the two methods.
You use grid[i].push_back(line); after you created 20 elements with grid[i].resize(WIDTH);. Method push_back add new element on the end of the vector, so new elements will have index 21, 22 .. 40.
You have two options:
you can set new values to initialized elements with some iterator, or
you can just skip resize and push new elements to empty vector. Simply delete those two lines:
for (int i = 0; i < HEIGHT; i++)
grid[i].resize(WIDTH);</li>
As an aside, it's generally considered bad practice to use a vector-of-vectors. Instead, use a class that wraps a single vector and does index arithmetic (either x*h+y or y*w+x depending on which major order you want).