I'm trying to learn how std::allocator works and I tried to do a simple task. The task is to delete for example the second element and to shift the elements to the left when the elements has been deleted.
For example, we have this as an input array: 1,2,3 and the output should look like 1,3. And what I get as input is: 1,3,3
This thing doesn't happen and that's why I'm here asking you.
But, when I have **std::allocator<string> myVar** instead of **std::allocator<int> myVar** it works.
Then the input: one, two, three and output is: one, three
Here's the code using std::allocator<int>:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
allocator<int> a1;
int* arr = a1.allocate(3);
for (int i = 0; i < 3; i++)
a1.construct(arr + i, i + 1);
a1.destroy(arr + 1);
a1.construct(arr + 1, 3);
for (int i = 0; i < 3; i++)
cout << arr[i] << " ";
cout << endl;
a1.deallocate(arr, 3);
return 0;
}
And here's the code with std::allocator<string>:
#include <iostream>
#include <memory>
#include <string>
using namespace std;
int main()
{
allocator<string> a1;
string* wrd = a1.allocate(3);
a1.construct(wrd, "one");
a1.construct(wrd + 1, "two");
a1.construct(wrd + 2, "three");
a1.destroy(wrd + 1);
cout << wrd[0] << " " << wrd[1] << " " << wrd[2] << endl;
a1.deallocate(wrd, 3);
return 0;
}
When you call allocator::destroy, it just destroys the object in the memory -- it doesn't do anything to the memory (its still there) or move anything. When you later try to do somthing with that memory, you get undefined behavior, but in the case of your strings, the "undefined behavior" turns out to be "act as if it was an empty string", so nothing gets printed.
If you were to call a1.construct(wrd+1, "three"); after the call to a1.destroy ins your string code (to make it the same as your int code), you would see it prints one three three
Related
Basically I have a vector that contains bits of binary and I want to resize the vector to be only the length of the useful info. The length of the Vector Is very large since it is holding user input, And I could not find a way to make the vector's length dynamic to the length of the users input.
so the vectors contents would essentially be ~
1001101010100110010110100000000000000000000000000000000
is there a way to shrink the vector to:
10011010101001100101101
myVector.shrink_to_fit();
doesn't solve my problem because the vector is populated with null data.
//Included Libraries
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Var Declerations
string inputText;
std::vector<int> ba; //ba=binary array* originally was an array
void displayBinaryVector()
{
for (int i = 0; i < ba.size(); i=i+8)
{
cout << ba.at(i) << ba.at(i+1) << ba.at(i+2) << ba.at(i+3) << ba.at(i+4) << ba.at(i+5) << ba.at(i+6) << ba.at(i+7) << endl;
}
}
//Main Function
int main()
{
// Gets input
cout << "Please Enter What You Would Like To Be Encoded" << endl;
getline(cin, inputText);
ba.resize((128*8));
convertToBinary();
displayBinaryVector();
return 0;
}
** edit ** clarified code (I think) and updated to my current solution.
I Think I have found A solution that works for my particular situation:
void displayBinaryVector()
{
for (int i = 0; i < ba.size();)
{
cout << ba.at(i) << ba.at(i+1) << ba.at(i+2) << ba.at(i+3) << ba.at(i+4) << ba.at(i+5) << ba.at(i+6) << ba.at(i+7) << endl;
i = i + 8;
if ((ba.at(i) + ba.at(i + 1) + ba.at(i + 2) + ba.at(i + 3) + ba.at(i + 4) + ba.at(i + 5) + ba.at(i + 6) + ba.at(i + 7)) == 0)
{
ba.resize(i);
}
}
}
I am still curious if there is a method or pre-written function that you can call that would essentially be reversing the vector searching until specified value/values are found and deleting any elements that have been 'checked'.
The following removes the right-most zero sequence from a vector<bool> (Also works for vector<int> with 0-1 values):
#include <algorithm>
vector<bool> ba {0,1,1,0,0,1,0,1,0,1,1,0,0,0};
ba.resize(ba.rend() - std::find(ba.rbegin(), ba.rend(), 1));
Using backward iterators, we find from the end the rightmost occurrence of 1. Then the vector is resized to the gap between the beginning and this found position. The solution is robust and applies for special cases of empty vectors and for vectors with pure zeros or ones.
My main idea is to shrink they array from both sides . For example if the input is 1234 , wanna print 1234 and then 4321 (the reversed) .
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int reversedArray(int* x)
{
cout<< "*x out of while =" << *x <<endl ;
while( *x != 0 )
{
cout << "*x=" << *x << endl;
cout<< "====================== im in reversed =================" << endl ;
return reversedArray( x+1 );
}
cout<< "after return " << *x << endl;
}
int main ()
{
int Array[] = {10,2,3,4,8 ,0} ;
int* p_Array = Array;
reversedArray( Array );
}
After the "while" , why the functions that are in the stack, do not return to the next line ( " the --> cout<< "after return " <<*x <
void printReversed(int * x)
{
if (*x == 0) return;
std::cout << *x;
printReversed(x+1);
std::cout << *x;
}
The line:
return reversedArray( x+1 );
exits the function. So you never repeat the while or execute any of the code after the while if you go into the while. This makes the while effectively an if statement.
The code posted by Crazy Eddie does the job and Barmar explains the ineffectiveness of the while loop. I decided to post a non-recursive way to address the problem mentioned.
#include <iostream>
#include <vector>
using namespace std;
vector<int> reverseArray(vector<int>& arr) {
vector<int> ans;
int n = arr.size();
// insert all elements in the reverse order
for (size_t i = 0; i < n; i++) {
ans.push_back(arr[n-i-1]);
}
return ans;
}
int main ()
{
int array[] = {10, 2, 3, 4, 8, 0};
// convert into vector
vector<int> arr(array, array+6);
vector<int> rev = reverseArray(arr);
// merging the 2 arrays
arr.insert(arr.end(), rev.begin(), rev.end());
// printArray(arr) -- implement to fit your needs;
}
When you pass an int[] to a function it decays to an int* which is simply an address in memory. C++ a better plan would be to use copy_backward with an ostream_iterator:
copy_backward(Array, Array + sizeof(Array) / sizeof(*Array), ostream_iterator<int>(cout, " "))
Note that this method uses the actual size of the array, and does not depend upon a terminal element. Thus, no numbers are offlimits, and it's impossible to segfault by failing to provide the terminating element.
If you have access to C++11 you can simplify that a bit further to:
copy(crbegin(Array), crend(Array), ostream_iterator<int>(cout, " "))
Live Example
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. */
string list[] = {"fiorello", "nonuterine", "asquint", "commodore", "semiprogressive",
"aviculturist", "brayley", "tendentious", "hungriness", "overbulkily",
"subfumigation", "praline", "fiorello", "presurvey", "unjealous",
"brayley", "unimpassionate", "welshman", "dcor", "traducianist"};
int size = sizeof(list);
for (int i = 0; i < size; i++) {
cout << list[i] << endl;
// THIS IS WHERE I REALIZE NOTHING ELSE PRINTS AFTER THIS POINT.
}
cout << endl;
int z = sizeof(list) / sizeof(list[0]);
sort(list, list + z);
for (int y = 0; y < z; y++) {
cout << list[y] << endl;
}
return 0;
}
I don't have a strong background in C++, coming from HTML, CSS etc. so trying to figure this out.
What I'm trying to accomplish is to print out the array, then print out in alphabetical order, then find duplicates and remove and print out again. And lastly, find length of each word in array and print that out.
As mentioned in comments, you are using sizeof incorrectly the first time. A good solution would be to not use it at all, instead use standard library algorithms which will find the size by template deduction:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string list[]={"fiorello","nonuterine","asquint","commodore","semiprogressive","aviculturist","brayley","tendentious","hungriness","overbulkily","subfumigation","praline","fiorello","presurvey","unjealous","brayley","unimpassionate","welshman","dcor","traducianist"};
// Operate on each item in list - don't need to mention count explicitly
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
// Same as sort(list, list+z)
sort( begin(list), end(list) );
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
}
Your comments suggest you plan to remove duplicates but you still want to use a C-style array. So presumably you'll be using a variable for the list count; you can get this by using:
size_t count = distance( begin(list), end(list) );
rather than using the sizeof thing. As well as being less error-prone, this will keep working even if you later change the code to use a container instead of a C-style array.
I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!
i'm trying to store some elements that is going to change every time, but i don't know which
way is better and why. I'm thinking about two ways, 1) declaring array of int and loop or
use vector's.
Which way is better and why?
Does declaring array of int have any future memore problems as leak?
the code down below show the two ways i'm talking about:
1)
#include <iostream>
#include <vector>
int main()
{
int x[5];
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
x[4] = 50;
for(unsigned int i = 0;i<=sizeof(x[5]); i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
2)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> x;
x.push_back(10);
x.push_back(20);
x.push_back(30);
x.push_back(40);
x.push_back(50);
for(unsigned int i = 0;i<=x.size()-1; i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
If this is all you have to do, and your array will always have a size that is known at compile time, then you do not need std::vector.
On the other hand, in C++11 you could use std::array instead of a plain C array (std::array is a zero-overhead, safer and more functional wrapper over a C array):
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> x = { 10, 20, 30, 40, 50 };
for (unsigned int i = 0; i < x.size(); i++)
// ^^^^^^^^
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
}
Here is a live example. Notice, that std::array offers a size() member function which you may want to use instead of the sizeof operator.
Moreover, since std::array is a standard sequence container, you could iterate through its element this way:
std::size_t i = 0;
for (auto e : x)
{
std:: cout << "x[" << i++ << "] = "<< e << std::endl;
}
Here is a live example.
If the size is known at compile time, use std::array. If not, use std::vector. In either case, use iterators to look at the elements:
typedef std::array<int> my_container_type;
typedef my_container::iterator iterator;
my_container_type my_container = { whatever };
for (iterator it = my_container.begin(); it != my_container.end(); ++it)
std::cout << "x[" << (it - my_container.begin()) << "] = " << *it << '\n';
By using iterators you greatly reduce the risk of accidentally using a loop limit like sizeof(x[5]), which is nonsense.
Neither is "better". They both address entirely different use cases.
If you know the array size at compile time and are 100% sure it will never change, sure, use a plain old array. It has less overhead, and the compiler can even aid you with static analysis by spotting any attempts to read outside the boundaries.
On the other hand, if you are unsure of the array's side (i.e. you will be reading input from a file or the user), then use the std::vector. It can grow to any size to meet your needs.