heap-buffer-overflow issue in array C++ [duplicate] - c++

So the user inputs values within the for loop and the vector pushes it back, creating its own index. The problem arises in the second for loop, I think it has to do something with sizeof(v)/sizeof(vector).
vector<int> v;
for (int i; cin >> i;)
{
v.push_back(i);
cout << v.size() << endl;
}
for (int i =0; i < sizeof(v)/sizeof(vector); i++)
{
cout << v[i] << endl;
}
How will I determine the size of the vector after entering values?
(I'm quite new to C++ so If I have made a stupid mistake, I apologize)

Use the vector::size() method: i < v.size().
The sizeof operator returns the size in bytes of the object or expression at compile time, which is constant for a std::vector.

How will I determine the size of the vector after entering values?
v.size() is the number of elements in v. Thus,
another style for the second loop, which is easy to understand
for (int i=0; i<v.size(); ++i)
A different aspect of the 'size' function you might find interesting:
on Ubuntu 15.10, g++ 5.2.1,
Using a 32 byte class UI224, the sizeof(UI224) reports 32 (as expected)
Note that
sizeof(std::vector<UI224>) with 0 elements reports 24
sizeof(std::vector<UI224>) with 10 elements reports 24
sizeof(std::vector<UI224>) with 100 elements reports 24
sizeof(std::vector<UI224>) with 1000 elements reports 24
Note also, that
sizeof(std::vector<uint8_t> with 0 elements reports 24
(update)
Thus, in your line
for (int i =0; i < sizeof(v) / sizeof(vector); i++)
^^^^^^^^^ ^^^^^^^^^^^^^^
the 2 values being divided are probably not what you are expecting.

http://cppreference.com is a great site to look-up member functions of STL containers.
That being said you are looking for the vector::size() member function.
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << endl;
}
If you have at your disposal a compiler that supports C++11 onwards you can use the new range based for loops:
for(auto i : v)
{
cout << i << endl;
}

A std::vector is a class. It's not the actual data, but a class that manages it.
Use std::vector.size() to get the size of the actual data.
Coliru example:
http://coliru.stacked-crooked.com/a/de0bffb1f4d8c836

Related

Insert numbers divisible by a number into a vector

I was given the integers 15, 16, 17 ,18 ,19 and 20.
I am supposed to put only the numbers divisible by 4 into a vector and then display the values in the vector.
I know how to do the problem using arrays but I'm guessing I don't know how to properly use pushback or vectors.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> arrmain; int i,j;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
}
}
return 0;
}
wanted output: Numbers divisible by 4: 16, 20
As already mentioned in the comments, you have a couple of problems in your code.
All which will bite you in the end when writing more code.
A lot of them can be told to you by compiler-tools. For example by using -Weverything in clang.
To pick out the most important ones:
source.cpp:8:10: warning: declaration shadows a local variable [-Wshadow]
for (int i = 15; i <=20 ; i++)
and
source.cpp:6:26: warning: unused variable 'i' [-Wunused-variable]
vector arrmain; int i,j;
Beside those, you have a logical issue in your code:
for values to check
if value is ok
print all known correct values
This will result in: 16, 16, 20 when ran.
Instead, you want to change the scope of the printing so it doesn't print on every match.
Finally, the bug you are seeing:
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
This bug is the result of poor naming, let me rename so you see the problem:
for(innercounter=0; innercounter<=arrmain.size(); innercounter++)
{
cout <<arrmain[outercounter]<< " "<<endl;
}
Now, it should be clear that you are using the wrong variable to index the vector. This will be indexes 16 and 20, in a vector with max size of 2. As these indexes are out-of-bounds for the vector, you have undefined behavior. When using the right index, the <= also causes you to go 1 index out of the bounds of the vector use < instead.
Besides using better names for your variables, I would recommend using the range based for. This is available since C++11.
for (int value : arrmain)
{
cout << value << " "<<endl;
}
The main issues in your code are that you are (1) using the wrong variable to index your vector when printing its values, i.e. you use cout <<arrmain[i] instead of cout <<arrmain[j]; and (2) that you exceed array bounds when iterating up to j <= arrmain.size() (instead of j < arrmain.size(). Note that arrmain[arrmain.size()] exceeds the vector's bounds by one because vector indices are 0-based; an vector of size 5, for example, has valid indices ranging from 0..4, and 5 is out of bounds.
A minor issue is that you print the array's contents again and again while filling it up. You probably want to print it once after the first loop, not again and again within it.
int main()
{
vector<int> arrmain;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
}
}
//output the elements in the vector
for(int j=0; j<arrmain.size(); j++)
{
cout <<arrmain[j]<< " "<<endl;
}
return 0;
}
Concerning the range-based for loop mentioned in the comment, note that you can iterate over the elements of a vector using the following abbreviate syntax:
// could also be written as range-based for loop:
for(auto val : arrmain) {
cout << val << " "<<endl;
}
This syntax is called a range-based for loop and is described, for example, here at cppreference.com.
After running your code, I found two bugs which are fixed in code below.
vector<int> arrmain; int i, j;
for (int i = 15; i <= 20; i++)
{
//checking which numbers are divisible by 4
if (i % 4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for (j = 0; j < arrmain.size(); j++) // should be < instead of <=
{
cout << arrmain[j] << " " << endl; // j instead of i
}
}
}
This code will output: 16 16 20, as you are printing elements of vector after each insert operation. You can take second loop outside to avoid doing repeated operations.
Basically, vectors are used in case of handling dynamic size change. So you can use push_back() if you want to increase the size of the vector dynamically or you can use []operator if size is already predefined.

finding even numbers in the array issue (C++)

My code is to extract odd number and even number in an 1D array.
#include <iostream>
using namespace std;
int main() {
int a[6] = {1,6,3,8,5,10};
int odd[]={};
int even[]={};
for (int i=0; i < 6; i++) {
cin >> a[i];
}
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 1) {
odd[i] = a[i];
cout << odd[i] << endl;
}
}
cout << " " << endl;
for (int i=0; i < 6; i++) {
if (a[i] % 2 == 0) {
even[i] = a[i];
cout << even[i] << endl;
}
}
return 0;
}
the output is:
1
3
5
2
1
6
It shows that it successfully extract odd numbers but the same method applied to the even number. It comes with an issue while the even number is 4.
Could anyone help me find the cause here? Thanks.
You've got an Undefined Behavior, so result may be any, even random, even formatted hard drive.
int odd[] = {} is the same as int odd[/*count of elements inside {}*/] = {/*nothing*/}, so it's int odd[0];
Result is not defined when you're accessing elements besides the end of array.
You probably have to think about correct odd/even arrays size, or use another auto-sizeable data structure.
First, although not causing a problem, you initialize an array with data and then overwrite it. The code
int a[6] = {1,6,3,8,5,10};
can be replaced with
int a[6];
Also, as stated in the comments,
int odd[]={};
isn't valid. You should either allocate a buffer as big as the main buffer (6 ints) or use a vector (although I personally prefer c-style arrays for small sizes, because they avoid heap allocations and extra complexity). With the full-size buffer technique, you need a value like -1 (assuming you intend to only input positive numbers) to store after the list of values in the arrays to tell your output code to stop reading, or store the sizes somewhere. This is to prevent reading values that haven't been set.
I don't understand your problem when 4 is in the input. Your code looks fine except for your arrays.
You can use std::vector< int > odd; and then call only odd.push_back(elem) whem elem is odd.

C++ Persistent Vector, fill vector with data from a text file

i am currently trying to learn some C++ and now i got stuck in an exercise with vectors. So the task is to read ints from a text file and store them in the vector which should be dynamic.
I guess there is something wrong with the while-loop?
If I start this, the program fails and if I set the vector size to 6, I get
6 0 0 0 0 0 as output.
Thanks for any hints.
int main()
{
const string filename = "test.txt";
int s = 0;
fstream f;
f.open(filename, ios::in);
vector<int> v;
if (f){
while(f >> s){
int i = 0;
v[i] = s;
i = i+1;
}
f.close();
}
for(int i = 0; i < 6; i++){
cout << v[i] << "\n";
}
}
You don't grow the vector. It is empty and cannot hold any ints. You'll need to either resize it every time you want to add another int or you use push_back which automatically enlarges the vector.
You set i = 0 for every iteration so you would change the first value of the vector every iteration instead of the next one.
Go for:
v.push_back(s);
in your loop and
for(int i = 0; i < v.size(); i++) { // ...
Remark:
You normally don't hardcode vector sizes/bounds. One major point about using std::vector is its ability to behave dynamically with respect to its size. Thus, the code dealing with vectors should not impose any restrictions about the size of the vector onto the respective object.
Example:
for(int i = 0; i < 6; i++){ cout << v[i] << "\n"; }
requires the vector to have at least 6 elements, otherwise (less than 6 ints) you access values out of bounds (and you potentially miss elements if v contains more than 6 values).
Use either
for(int i = 0; i < v.size(); i++){ cout << v[i] << "\n"; }
or
for(std::vector<int>::const_iterator i = v.begin(); i != v.end(); ++i)
{
cout << *i << "\n";
}
or
for(auto i = v.begin(); i != v.end(); ++i)
{
cout << *i << "\n";
}
or
for(int x : v){ cout << x << "\n"; }
or
for(auto && x : v){ cout << x << "\n"; }
or
std::for_each(v.begin(), v.end(), [](int x){ std::cout << x << "\n"; });
or variants of the above which possibly pre-store v.size() or v.end()
or whatever you like as long as you don't impose any restriction on the dynamic size of your vector.
The issue is in the line i= 0. Fixing that will give an issue in the line v[i] = s.
You always initialise i to 0 in the while loop, and that is responsible for the current output. You should shift it out of the while loop.
After fixing that, you have not allocated memory to that vector, and so v[i] doesn't make sense as it would access memory beyond bounds. This will give a segmentation fault. Instead, it should be v.push_back(i), as that adds elements to the end of a vector, and also allocates memory if needed.
If you are using std::vector you can use v.push_back(i) to fill this vector
Error is this line int i = 0;
because you declare i=0 every time in while-loop.
To correct this move this line outside from loop.
Note: this will work, if you declare v like normal array for example int v[101]
When you use std vectors you can just push element at the end of vector with v.push_back(element);
v[i] = s; //error,you dont malloc room for vector
change into : v.push_back(s);

c++: vector of vector issue

I wrote a c++ code where i'm testing the running time of vector push_back. I have a vector of vector. I called my main vector, mainVec, and embedded vector, subVec. So, I push backed 2^20 elements into subVec and then push backed subVec 2^20 times into mainVec. However, in the loop of subVec-push_back I have a cout command which doesn't get executed. I was hoping you can point out my mistake.
Here is the code (There is no error in the code, though):
vector<int> subVec;
vector< vector<int> > mainVec;
//Fills the subvector with 2^20 elements
for( size_t i = 0; i < (pow(2,20)+1); ++i) subVec.push_back(i);
//Filling of the maiVec with 2^20 subVec
for( size_t j = 10; j < 21; ++j) {
cout << pow(2,j) << endl;
clock_t t1 = clock();
//2^j times subVec is push_backed for j < 21
for( size_t k = 0; k < pow(2,j); ++k ) mainVec.push_back( subVec );
t1 = clock()-t1;
//Outputting to file
cout << "\t" << (float(t1) / CLOCKS_PER_SEC) << endl;
//ofs << pow(2,j) << "\t\t" << (float(t1) / CLOCKS_PER_SEC) << endl;
}
There are several issues with your code.
First, you don't need the +1 in the first loop, i.e,. pow(2,20)+1. Since you're starting with 0 and you want 2^20 times, you need to do until i<2^20.
Second, it's better to calculate the pows before the loop, otherwise it will calculate them each time and that could take forever.
Third, you can do 1<<j instead of pow(2,j). Just FYI.
Forth, and most important, we are talking about a tremenduous amount of memory here. Even your smallest loop is doing 2^30 ints which is 4GB of memory. My guess is that your program is just killing your computer and the reason it never prints the second cout is that it doesn't get there (because it's trying to use swap file for the memory). Try using smaller numbers, say 2^10 for the first loop, and see if you get the outputs.

Why can't I insert 6 million elements in STL set?

I am trying to insert a little over 6.5 million elements(ints) in an stl set. Here is the code:
set<int> s;
cout << s.max_size() << endl;
for(int i = 0; i < T.MULT * T.MAXP; i++) {
s.insert(a[i]);
}
T.MULT is 10; T.MAXP is 666013.
a is an array - statically allocated - (int a[T.MULT * T.MAXP];) that contains distinct elements.
After about 4.6 million elements s.insert() throws a bad_alloc exception. The resource monitor available on Windows 7 says I have 3 GB free memory left.
What am I doing wrong? Why can't STL set allocate the memory?
Edit: Here is the full code: http://ideone.com/rdrEnt
Edit2: apparently the inserted elements might not be distinct after all, but that should not be a problem.
Edit3: Here is a simplified version of the code: http://ideone.com/dTp0fZ
The problem actually lies in the fact that you statically allocated the array A with more than 6.5 million elements, which corrupts your program stack space. If you allocate the array on the heap, it actually works. I did some code change based on your description, it worked fine.
int *A = new int[T.MULT * T.MAXP];
for (int i= 0; i < T.MULT * T.MAXP; ++i)
{
A[i] = i; //for simplicity purpose, your array may have different elem. values
}
set<int> s;
for (int i = 0; i < T.MULT * T.MAXP; ++i )
{
s.insert(A[i]);
}
cout << s.size();
set<int>::iterator iter;
int count = 0;
for (iter = s.begin(); iter != s.end(); ++ iter)
{
cout << *iter << " ";
count ++;
if (count == 100)
{
cout <<endl;
count = 0;
}
}
delete [] A;
return 0;
It worked perfectly fine with both vector and set. It can print all those 6.6 million elements on the screen.
As other posts indicated, you may also want to try STXXL if you have interest.
You might want to take a look at STXXL.
While I can't answer your question directly, I think it is more efficient to store your data in a std::vector, sort it, and then use std::binary_search to test for the existence of the item. Storage in a std::set is relatively expensive compared to that of std::vector. That's because there is some overhead when storing each element.
As an example, here's how you could do it. This sorts the static array.
std::sort(a,a+(T.MULT*T.MAXP));
bool existence=std::binary_search(a,a+(T.MULT*T.MAXP),3);
Fast and easy.