You are expected to use std::make_shared to ensure that block with counters is stored next to data. Unfortunately internally std::make_shared uses zero initialization for T (i.e. uses T() to initialize data block). Is there any way to trick it into using default initialization? I know I can use std::shared_ptr( new T, [](auto p){delete p;}), but I'll end up with two allocations here (data and counter blocks won't be next to each other)
mardi 31 janvier 2017
Validating test code against actual string content _M_dataplus._M_p
When copying strings, I noticed that the actual string content is preserved/reused but a new std::string constructor wraps around it.
I'm writing a lengthy unit test code on C++ std::string
handling (also applies to std::wstring
) and ensuring that it didn't get overwritten inside nested function.
My problem stems from my own poorly-written C++ test case where I am UNABLE to create a unique string content without being subjected to compiler-optimized away the duplicate constant strings.
std::wstring unique_test_str1 = L"counter";
std::wstring unique_test_str2 = uniqueteststr1;
GNU debugger (gdb
) reports:
gdb> p unique_test_str1._M_dataplus._M_p
unique_test_str1._M_dataplus._M_p = 0x6173a8 L"counter"
gdb>
gdb> p unique_test_str2._M_dataplus._M_p
unique_test_str2._M_dataplus._M_p = 0x6173a8 L"counter"
Test code fails because I am unable to test for actual address of string content (via ._M_dataplus._M_p
). Yet it passes as having a unique pointer to each string constructor.
assert( unique_test_str != unique_test_str2 );
And I cannot write a unit test against a private _M_p
variable of a basic_string class.
I'm sure it is something stupid, but how does one make sure that each and all L"counter"
constant string is unique?
C++ code runs forever and eats memory
It seems to be in MakeData function, as that is what breaks the execution. I am very unsure as to why this is not working, as my instructor and many of my classmates have almost identical execution and it is fine. I know for a fact that an almost identical version of this code, with windows file name, also does not run on windows. I have compiled the code. I have run debuggers. Nothing turns up. The debuggers I have run have just run the code until either very obscure errors turn up or it essentially indicates that the process is in some kind of an infinite loop. Any help would be appreciated!
/*
*Program Description:A program to sort a series of strings and scores from a file.
*
*Programmer:Timothy A. Gass
*Date:01/17/17
*/
#include <iostream>
#include <string>
#include <math.h>
#include <fstream>
#include <vector>
#include <ctime>
using namespace std;
void makeData(string);
void getData(vector<string> &, vector<int> &, string);
int main(){
srand(time(0));
string fname = "/home/tim/dev/c++/chpt9/data.txt";
vector<string> name;
vector<int> score;
makeData(fname);
getData(name, score, fname);
for(int i = 0; i < score.size(); i++){
cout << score[i] << endl;
cout << name[i] << endl;
}
cout << "Press enter to exit." << endl;
cin.ignore();
cin.get();
return 0;
}
void makeData(string fname){
int rand1, rand2, rand3;
const int SCORE_MAX_SIZE = 100;
ofstream make(fname);
const int PEOPLE_NUM = 50;
vector<string> firstNames = {
"Gus",
"Taneka",
"Shane",
"Rosella",
"Bennett",
"Filiberto",
"Khadijah",
"Mafalda",
"Rusty",
"Janiece",
"Shavonne",
"Azalee",
"Enedina",
"Heidy",
"Lavelle",
"Darleen",
"Ashton",
"Glynis",
"Gale",
"Norene",
"Madaline",
"Elvin",
"Jacqueline",
"Kristofer",
"Zachary",
"Lorretta",
"Jim",
"Shanelle",
"Tonja",
"Alethia",
"Kasha",
"Katheleen",
"Joyce",
"Kirstin",
"Neil",
"Belkis",
"Maisha",
"Doretha",
"Eliseo",
"Rhiannon",
"Annamarie",
"Latoria",
"Jerica",
"Betsey",
"Delinda",
"Pamula",
"Porsha",
"Fredia",
"Wilda",
"Belen"
};
vector<string> lastNames = {
"Best",
"Shields",
"Finley",
"Blankenship",
"Hobbs",
"Nichols",
"Mcneil",
"Robles",
"Moyer",
"Hays",
"Elliott",
"Ruiz",
"Ritter",
"Gamble",
"Zamora",
"Cole",
"Larson",
"Ibarra",
"Choi",
"Santana",
"Gray",
"Crane",
"Campos",
"Wright",
"Morris",
"Flores",
"Newman",
"Santos",
"Li",
"Archer",
"Chavez",
"Avery",
"Mora",
"Liu",
"Lutz",
"Miles",
"Stewart",
"Austin",
"Wu",
"Turner",
"Brennan",
"Ferrell",
"Mcmillan",
"Whitney",
"Odonnell",
"Conley",
"Maxwell",
"Stafford",
"Carlson",
"Peck"
};
for(int i = 0; i < PEOPLE_NUM; i++){
rand1 = rand()%50;
rand2 = rand()%50;
rand3 = rand()%(SCORE_MAX_SIZE+1);
make << firstNames.at(rand1) + " " + lastNames.at(rand2) << endl;
make << rand3 << endl;
}
}
void getData(vector<string> &name, vector<int> &score, string fname){
ifstream get(fname);
string str;
int num;
if(get.fail()){
cout << "File could not be opened!" << endl;
}
else
{
while(!get.eof())
{
getline(get, str);
get >> num;
cin.ignore();
name.push_back(str);
score.push_back(num);
}
}
}
Why running std::thread with empty function spend a lot of memory
I wrote a simple program which should run two threads, sort small array (~4096 Byte) and write into an output file. Input data contain in the one big file (~4Gb). Computer has 128MB memory. I found that running just empty main function use 14MB memory. If run std::thread with empty function application start to use ~8MB per thread. BUT if i make just one dynamic memory allocation program starts to use approximately 64Mb per thread. I don't understand what can spend so much memory. How can I control this size? And how allocate dynamic memory to minimize some system default allocation?
- System: Ubuntu 14.04.3
- Compiler: gcc 4.8.4
-
Compiler option:'-std=c++11 -O3 -pthread'
-
This is a code example
void dummy(void) { std::vector<unsigned int> g(1); int i = 0; while( i<500000000) { ++i; } } int main(void) { std::thread t1(&dummy); std::thread t2(&dummy); std::thread t3(&dummy); t1.join(); t2.join(); t3.join(); return 0; }
Is it possible to fan-out an istream to multiple readers?
I have an std::istream
to work with. Is it possible to somehow pass it on to multiple readers which will potentially seek to and read from different positions?
If not, what if I restrict it to the case of an std::ifstream
?
Addition and Increment expression in [ ] - operator
According to the standard are the following two expressions undefined behavior ?
int a = 1, b = 1;
int c[] { 1, 2, 3, 4, 5 };
// Do the following expressions lead to Undefined Behavior ?
c[a++]; // (1)
c[a+b]; // (2)
Results change based on non-modifying code
I am working off of a linux server, and I am trying to work with strings as lengths of DNA. I am trying to see if I can make one set of DNA "collide" with another set. Collide just means that two sequences are the same, but they did not originate from the same length of DNA.
Here is the data, in 5test.txt:
03111
11013
22002
22133
33122
33121
Here is main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <typeinfo>
using namespace std;
inline string insert(const string& who, int where, string what)
{
string temp = who;
temp.insert(where, what);
return temp;
}
struct c_mDNA //holds the DNA sequences, remembering where it came from
{
string seq;
const string* orig;
};
ostream& operator<<(ostream& os, c_mDNA& m) //to print out debug info easier
{
os << "seq: " << m.seq << "\torig: " << *m.orig << endl;
return os;
}
int main()
{
ifstream input; string inputname; //These next couple lines deal with input
inputname = "5test.txt";
input.open(inputname.c_str());
string line; //line will hold the inputted lines
int n = 5; //we're working with length 5 as a test
vector<string> oDNA; //this holds all of the original strands
vector<c_mDNA> mDNA, iDNA; //this will hold all of the mutated strands, m being the deleted and i being the possible insertions
//input loop
while (getline(input, line))
{
//change line from a sequence of numbers to nucleotide ACTG
...
oDNA.push_back(line);
}
//insert loop
for(auto oliga : oDNA)
{
for (int i = 0; i < n; i++)
{
iDNA.push_back(c_mDNA { insert(oliga, i, "A"), &oliga } );
cout << iDNA.back() << endl;
//do the above for the other 3 nucleotides
...
}
//these next couple lines are important
//for (auto m : iDNA)
//{
// cout << m << endl;
//}
}
//mutate loop
for (auto& oliga : oDNA)
{
for (int i = 0; i < oliga.length(); i++)
{
string temp = oliga;
temp.erase(i,1);
//There are 16 different combinations of two nucleotides
mDNA.push_back(c_mDNA{temp + "AA", &oliga});
mDNA.push_back(c_mDNA{temp + "CA", &oliga});
mDNA.push_back(c_mDNA{temp + "TA", &oliga});
mDNA.push_back(c_mDNA{temp + "GA", &oliga});
mDNA.push_back(c_mDNA{temp + "AC", &oliga});
mDNA.push_back(c_mDNA{temp + "CC", &oliga});
mDNA.push_back(c_mDNA{temp + "TC", &oliga});
mDNA.push_back(c_mDNA{temp + "GC", &oliga});
mDNA.push_back(c_mDNA{temp + "AT", &oliga});
mDNA.push_back(c_mDNA{temp + "CT", &oliga});
mDNA.push_back(c_mDNA{temp + "TT", &oliga});
mDNA.push_back(c_mDNA{temp + "GT", &oliga});
mDNA.push_back(c_mDNA{temp + "AG", &oliga});
mDNA.push_back(c_mDNA{temp + "CG", &oliga});
mDNA.push_back(c_mDNA{temp + "TG", &oliga});
mDNA.push_back(c_mDNA{temp + "GG", &oliga});
}
}
//check loop
for (auto m : iDNA)
{
cout << m << endl;
}
ofstream out("5out_test.txt");
int collisions(0);
//output loop
for (const auto& m_oliga : mDNA)
{
bool collide = false; c_mDNA collude; //collude stores the collided codeword
for (const auto& i_oliga : iDNA)
{
if (m_oliga.seq == i_oliga.seq) //if sequences are the same
{
if ( m_oliga.orig != i_oliga.orig) //if the original seqs are the same
{
cout << *m_oliga.orig << " and " << *i_oliga.orig << endl;
cout << m_oliga.orig << " and " << i_oliga.orig << endl;
collide = true;
collude = i_oliga;
collisions++;
break;
}
}
}
if (collide) out << m_oliga.seq << " orig: " << *m_oliga.orig << " collides with: " << collude.seq << " from: " << *collude.orig << endl;
else out << m_oliga.seq << " orig: " << *m_oliga.orig << endl;
}
return 0;
}
I have labelled the five loops "input", "insert", "mutate" "check" and "output". there is a copy of the "check" loop inside of the "insert" loop that I have commented out.
This is creeping me out. When I leave that copy commented, I get garbage like this output from the "check" loop:
seq: GCGTAT orig: GCGTAT
orig should be a length 5 string, and it should be pointing to an element in the oDNA vector. From the "output" loop, when it finds a collision, it prints this out to the screen:
GGGTA and
0x61cf80 and 0x7fffffffd6a0
the first line doesn't print anything for *i_oliga.orig. The pointer is still pointing somewhere.
Now when I uncomment the first "check" loop:
seq: GCGTAT orig: GCGTT
GGGTA and GCGTT
0x61cf80 and 0x7fffffffd650
For some reason, the pointer is still pointing to a completely different place, but I am getting the answer that I want. i have tested to make sure that this is consistent behavior.
Why does the commented out loop change the results?
Another thing that might be useful to know is that when I import main.cpp and 5test.txt to my home computer and run the program on visual studio 15, I only ever get garbage results.
Noexcept for classes that use a stringstream
I have a class that has a std::stringstream
member:
class Buffer
{
std::stringstream ss_;
};
Its move constructor is
Buffer::Buffer(Buffer&& buf)
: ss_(std::move(buf.ss_))
{
}
I suspect that the move operation will not throw and the move constructor could be noexcept
because of this. So my questions are:
- How do I determine if a function from the STL is declared
noexcept
, for examplestd::stringstream::str
? - If swapping or moving the
stringstream
was notnoexcept
, could I still declare theBuffer
membersnoexcept
and get a call tostd::unexpected()
if an exception is thrown by thestringstream
? From what I can find that would be the case. - Is there a way around the problem, for example an alternate container that can be written to using the stream operators and that is
noexcept
?
Warn about calling copy ctor when std::move'ing
Given a program:
#include <iostream>
#include <vector>
using namespace std;
struct Vec {
Vec() = default;
Vec(const Vec& vec)
: v_(vec.v_)
{
cout << "copy Vec" << endl;
}
Vec(Vec&& vec)
: v_(std::move(vec.v_))
{
cout << "move Vec" << endl;
}
vector<double> v_{};
};
struct T1 {
Vec Value;
};
struct T2 {
T2(const T1& t1)
: Value(std::move(t1.Value))
{
}
Vec Value;
};
struct T3 {
T3(T1&& t1)
: Value(std::move(t1.Value))
{
}
Vec Value;
};
int main() {
T1 t1;
T2 t2{ t1 };
T3 t3{ std::move(t1) };
return 0;
}
Output:
copy Vec
move Vec
In both cases I std::move
'ing t1.Value
to Vec
ctor.
Is there any possibility to enable some warning in Clang (or another compiler) so it warns me that moving actually calls copy constructor?
(Clang already can warn about performance issues when, for example, I return a std::unique_ptr
by std::move(result)
from function.)
Conversion and move ctor leads to ambiguous call for Clang and GCC 4.9.2
I am a bit stumped by the following conversion problem in C++11. Given this code:
#include <utility>
struct State {
State(State const& state) = default;
State(State&& state) = default;
State() = default;
int x;
};
template<typename T>
struct Wrapper {
T x;
Wrapper() = default;
operator T const&() const& { return x; }
// version which also works with GCC 4.9.2:
// operator T&&() && { return std::move(x); }
// version which does not work with GCC 4.9.2:
operator T() && { return std::move(x); }
};
int main() {
Wrapper<State> x;
State y(std::move(x));
}
godbolt link to the failed compilation with Clang
In the form above, g++ starting at version 5.1 and ICPC version 16 and 17 compile the code. If I uncomment the T&&
conversion operator and comment-in the currently-used second one:
operator T&&() && { return std::move(x); }
// version which does not work with GCC 4.9.2:
// operator T() && { return std::move(x); }
then GCC 4.9 also compiles. Otherwise, it complains:
foo.cpp:23:23: error: call of overloaded ‘State(std::remove_reference<Wrapper<State>&>::type)’ is ambiguous
State y(std::move(x));
^
foo.cpp:23:23: note: candidates are:
foo.cpp:5:3: note: constexpr State::State(State&&)
State(State&& state) = default;
^
foo.cpp:4:3: note: constexpr State::State(const State&)
State(State const& state) = default;
However, clang never compiles the code, equally complaining about an ambiguous call to the constructor of State
.
This, I do not understand. Given the std::move(x)
, I would expect to have an rvalue of type Wrapper<State>
. Then, shouldn’t the conversion operator T&&() &&
be clearly better than the T const&() const&
one? And given that, shouldn’t the rvalue-reference constructor of State
be used to construct y
from the rvalue-reference return value of the conversion?
Can someone explain the ambiguity to me and ideally also whether Clang or GCC (and if so, in which version) is right?
How to obtain the content of rapidjson::StringBuffer?
A function like this:
std::string getJson()
{
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
// calling writer events....
return {buffer.GetString(), buffer.GetSize()};
}
is not an option as it will deep copy the content of buffer
to the returning std::string
, while the point is to reuse the content.
Changing the return type to const char *
and just doing return buffer.GetString();
(or changing the return type to std::string_view
and just doing return {buffer.GetString(), buffer.GetSize()};
), is not an option as well as it seems the destructor of buffer
deallocates the internal storage so the returned pointer will actually be dead.
The question is how can I prevent the deallocation of the content by sort of "taking" the ownership from buffer
?
Adopt custom allocators into well-managed code - chain of command (using RAII?)
This is a very long question. The first half is situation/question, and the second half are my poor solutions.
I am working on a game project that, in my opinion, have a neat architecture.
Below is a simplified diagram of the whole architecture.
(No need to concern much about the class / function names.)
From above diagram, all code can be roughly divided into 3 layers. (red/orange/green)
-
Red (The big guys):
EverySystem_XXX
are derived fromSystem_Default
.
They call below layers, and sometimes call other red. -
Orange:
It contains a lot of game-specific library.
In short, they are just a utility to support the red. -
Green:
It is a utility to support red and orange.
It contains all of basic function.
The code is designed to be used by many games.
Most heap allocation (99% of new/delete) happen here.
Here is a snippet show how most functions are called:-
class System_EnemyAI : public System_default{
public: void update(){
EntityPointer entity= .... ;
systemGet<System_Projectile>()->damage(entity);
//^ system always call another system using this template function
TempMathState mathState;
mathState.someFunction( .... );
......
}
//... other member / function
}
class TempMathState{
MyArray<float> stateList; //<-- need dynamic allocation
//...... other member / function
}
Everything works fine until my greedy boss tell me that I should use custom allocators.
The proposal
-
Each
System_XXX
should have its own memory pool to promote data-coherence.
System_XXX
= all system the derived fromSystem_Default
Advantage: Less fragmentation, less cache miss, sound good! -
We know that 99% of function flow can be depicted similar as the black chains of command (below diagram).
-
In the left chain (1), starts at
findThreat()
,
the big guy in this chain isSystem_EnemyAI
.
Therefore, all memory allocation in the chain should use memory pool ofSystem_EnemyAI
. -
In the right chain (2), starts at
update()
,
the last big guy in this chain isSystem_Projectile
(via::damage(entity)
).
Therefore, all memory allocation in the chain should use memory pool ofSystem_Projectile
.
The logic looks reasonable, everyone agrees, end of meeting.
Question
What is the least painful approach to achieve this?
Soft requirement:-
- I don't have to refactor most function of most classes.
- It should support multi-threading.
My poor solutions
All three approaches share a certain disadvantage :-
I have to add at least one statement in every function in System-layer.
Solution 1
Pass custom allocator down to the chain.
Most functions in all layers have to receive allocator
as a parameter.
class System_EnemyAI : public System_default{
public: void update(){
.....
systemGet<System_Projectile>()->damage(this->allocator,entity); //ugly
TempMathState mathState=TempMathState(this->allocator); //ugly
}
}
Disadvantage:
- That would be an exhaustive refactoring!
- All code will look more ugly.
Solution 2A
Set a static global flag.
class System_EnemyAI : public System_default{
public: void update(){
GLOBAL_HEY_USE_ALLOCATOR = this->allocator;
.... other code ...
systemGet<System_Projectile>()->damage(entity); //don't change :)
GLOBAL_HEY_USE_ALLOCATOR = this->allocator;
//^ #steal the flag back,
// because it was stolen by System_Projectile (see below)
TempMathState mathState=TempMathState(); //don't change :)
}
}
It have to do in all function :-
class System_Projectile : public System_default{
public: void damage(EntityPointer entity){
GLOBAL_HEY_USE_ALLOCATOR = this->allocator; //#steal the flag
.... other code ...
}
}
#steal
: because the callee function (System_Projectile
) will set GLOBAL_HEY_USE_ALLOCATOR
, so caller (System_EnemyAI
) have to set GLOBAL_HEY_USE_ALLOCATOR
back.
Any allocation will use the Allocator* GLOBAL_HEY_USE_ALLOCATOR
as a memory pool.
This part is not hard.
Disadvantage:
- It uses global flag, so it doesn't support multi-threading.
- I have to set many flags manually.
Solution 2B
Use RAII to limit scope and manipulate constructor/destructor :-
class System_EnemyAI : public System_default{
public: void update(){
AllocatorScope scope = AllocatorScope(this->allocator);
//^ push "this->allocator" into a global stack
.... other code ...
systemGet<System_Projectile>()->damage(entity); //don't change :)
TempMathState mathState=TempMathState(); //don't change :)
}
};
class System_Projectile : public System_default{
public: void damage(EntityPointer entity){
AllocatorScope scope = AllocatorScope(this->allocator);
.... other code ...
//the "scope" is deleted, so pop stack to recover the previous state
}
};
Disadvantage:
- It still uses global variable, so it doesn't support multi-threading.
Lazy evaluation in C++14/17 - just lambdas or also futures etc?
I just read:
and noticed it's kind of old and most of the answers regard pre-2011 C++. These days we have syntactic lambdas, which can even deduce the return type, so lazy evaluation seems to boil down to just passing them around: Instead of
auto x = foo();
you execute
auto unevaluted_x = []() { return foo(); };
and then evaluate when/where you need to:
auto x = unevaluted_x();
Seems like there's nothing more to it. However, one of the answers there suggests using futures with asynchronous launching. Can someone lay out why/if futures are significant for lazy-evaluation work, in C++ or more abstractly? It seems as though futures may very well be evaluated eagerly, but simply, say, on another thread, and perhaps with less priority than whatever created them; and anyway, it should be implementation-dependent, right?
Also, are there other modern C++ constructs which are useful to keep in mind in the context of lazy evaluation?
What is the best way to access data from file in random?
I have been searching for an answer for this question, but I found none. I'm currently using fstream
to open a file on the hard-disk with flags std::ios_base::in | std::ios_base::out | std::ios_base::binary
for random access.
The data present in the file are records and each record is of size 16 bytes
. And it took about 0.479604 seconds
to write 336.357 kb
of records to the file in parallel (two threads). I didn't use any specific strategy to perform the read write operation optimally. And without threads, the same operation took 0.352716 seconds
(the time difference is as expected).
These are the methods I used for performing the read write operations:
void FileBascIO::createFile(const std::string& fName) {
std::fstream fcreate(fName.c_str(), std::ios_base::out | std::ios_base::binary);
}
FileBascIO::returnTypeRead FileBascIO::readFromFile(const std::string& fName, int64_t pos,
FileFlagType relativeInitial, char* data, uint64_t size) {
std::fstream fio (fName.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
fio.seekg(pos, relativeInitial);
return fio.read(data, size);
}
FileBascIO::returnTypeWrite FileBascIO::writeToFile(const std::string& fName, int64_t pos,
FileFlagType relativeInitial, char* data, uint64_t size) {
std::fstream fio (fName.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
if (!fio) {
fio.close();
fio.clear();
createFile (fName);
fio.open(fName.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
}
fio.seekp(pos, relativeInitial);
return fio.write(data, size);
}
The above code is not efficient and I don't know any ways of making it efficient. I did a bit of searching on this and I came to understand that the entire file or a large block of the file should be pre-read and stored in the RAM, before performing the operations. This is because the physical position of the data in the hard-disk matters. And once the fields get updated, the entire file must be written back to the hard-disk in large blocks.
In the example of writing 16 bytes to the file sequentially, won't it be better to first store the data in the RAM memory first and write that to the file in large blocks? If I were to do this manually, what block size should I choose? What is the best alternate way to implement random read/write access more efficiently?
lundi 30 janvier 2017
Operator overloading on template: unresolved external when used in another project
In project X, I define the following:
// x.h - library X
template<typename T>
struct square
{
DLL_API T operator()( T const& left, T const& right ) const;
};
// x.cpp - library X
template<typename T>
T square<T>::operator()( T const& left, T const& right ) const
{
return ( left + right*right );
}
// macro
#ifdef DLL_EXPORTS // DLL export macros
#define DLL_API __declspec(dllexport)
#define DLL_TEMPLATE
#else
#define DLL_API __declspec( dllimport )
#define DLL_TEMPLATE extern
#endif
Then I use it in another project, which links to the library with above definitions:
// y.cpp - library Y
std::accumulate( std::begin(x), std::end(x), 0.0, square<double>() );
Resulting in the unresolved external:
Error 2 error LNK2019: unresolved external symbol "__declspec(dllimport) public: double __cdecl square::operator()(double const &,double const &)" (__imp_??R?$square@N@QEAANAEBN0@Z) referenced in function "double __cdecl std::_Accumulate >(double *,double *,double,struct square)" (??$_Accumulate@PEANNU?$absolute@N@std@@YANPEAN0NU?$square@N@)
When I use the square<double>()
within x.cpp
, template function is being instantiated, and project Y builds fine and everything works OK.
I tried defining the operator inline and also forward declare it, but the linker error still remains.
What's the best way to resolve the error, assuming the operator is not being used in x.cpp
file and, ideally, keeping the implementation in cpp file?
What happens to previous data on new assignment?
Consider the following code -
{
int n = 3;
n = 5;
std::vector<int> v = { 1, 2, 3 .... 3242};
v = std::vector<int>{10000, 10001, 10002... 50000};
}
for primitive data types like int
, it can simply overwrite the previous memory location with the new value and get away with it. However what happens to types like std::vector
, where sizes of previous value might not be same as the new assignment.
In other words, what happens to the part { 1, 2, 3 .... 3000}
when v is reassigned to new {10000, 10001, 10002... 50000}
value. Does it simply throw away the previous value and reassign the internal pointers to new locations? Or does it overwrites the previous locations with new data as much as it can, and either reallocates new memory in case of large assignment or clears out existing memory in case of shorter assignment thus preserving the capacity()
of initial vector?
Would this be preferable anywhere over clearing out the contents (.clear()
) instead because I saw this type of code somewhere?
Declaring Dynamic array in a function
I am making a function that re-allocate a new dynamic array if the previous array is full. However, If I compile it, a run-time error happens. When I debug it with Visual Studio 2015, it seems that, after function is done, the compiler cannot access to the dynamic array or the array is deleted. Can you tell me why?
void reallocateMemory(string* arr, int& physicalSize, int addedMemory) {
string* result = new string[physicalSize + addedMemory];
for (int i = 0; i < physicalSize; i++) {
result[i] = arr[i];
}
delete[] arr;
arr = result; // After this code, it seems variable arr works well.
result = nullptr;
physicalSize += addedMemory;
} // However, when the function returns, arr cannot access a dynamic array.
Assure, function runs under lock_guard
I have a function foo()
which is called from different places in a heavy multi-threaded environment.
It is modifying some sensitive data but due to the complexity I cannot use inside this function std::lock_guard...
- this must be assured by the caller function. The reason is that the function is called several times in a row and the modified data [inside foo()
] must not be touched in the meantime by other thread until the one thread finished all modifications by the several calls of foo()
.
We all are human - and especially me - and I was thinking about a way how to assure that the function foo()
is indeed under the lock_guard...
control and I just didn't forget to lock the scope.
For me - running under gcc and I don't have to consider any platform independent solution - I found this way:
auto foo( __attribute__ ((unused)) std::lock_guard<std::mutex> & guardActive ) -> void
{
...
}
Then, foo()
must be called like this, otherwise already gcc does not compile it:
std::lock_guard<std::mutex> lockScope( mutexObject );
...
foo( lockScope );
...
My question:
Is this way OK, or are there better solutions? Reentrant mutex cannot be used.
Making a const unique_ptr then trying to std::move from it gives the same error as if you were trying to access the copy constructor
I noticed the error when we try to copy a unique_ptr (e.g. assign one unique pointer to another) is
Error C2280 'std::unique_ptr
#include <memory>
int main()
{
std::unique_ptr<int> a = std::make_unique<int>(2);
std::unique_ptr<int> b = a;
}
That's fine, as unique_ptr don't have a copy constructor defined. You don't copy from unique pointers to move (transfer ownership) of the pointer between them.
Interestingly (OK maybe not), but this code throws the same error. Now I know that it's not valid (I declared the first unique_ptr as a immutable object), but the error message implies it is trying to call the copy constructor. Is that correct?
#include <memory>
int main()
{
const std::unique_ptr<int> a = std::make_unique<int>(2);
std::unique_ptr<int> b = std::move(a);
}
in C++ can future/promise be efficiently used to implement a concurrent producer/consumer pattern?
I am looking to see if Future/Promise can be used efficiently to implement the Producer/Consumer pattern. Would it be more efficient than the standard pattern that usually has a busy wait in the consumer?
The idea came to me as I came across an example of implementing Producer/Consumer in c# using task/async http://ift.tt/2kamkXr
Clarification on C++11 const
I've been looking all over to try and figure out when const
should be used and what it does. I thought I had a decent grasp but it looks like the C++11 standard has changed some things.
Are the below true?
True for all versions of c++
const int integer = 3;
- integer can not be changed
const someObject();
- someObject can not be changed (except for mutable things)
void someMethod() const
- someMethod is not allowed to change any members of it's object. (If both void someMethod()
and void someMethod() const
exist, non-const objects will call void someMethod()
and const objects will call void someMethod() const
.
const int getMyInteger()
- returns an int that can't be changed (c++11 essentially makes obsolete with rvalues)
void doSomething(const int& integer)
- integer's const reference (integer is readonly) is passed rather than passed by value. (preferred over pass by value before c++11)
void pointerMethod(const ptr* pointer)
- not preferred for C++ since references can be used and were designed to be safer. (Basically the same as pass by const reference above minus dereferencing and pointer algebra.)
Prior to C++11
void doSomething(const int integer)
- basically meaningless since a copy is formed anyway. Essentially serves as self-documentation that the copy is not changed in the function/method.
Since C++11
void doSomething(const int integer)
- preferred way to pass parameters since move semantics will move rvalue with guarantee that the object being moved will not be changed. Use whenever possible.
void notCopying(const SomeHugeObject hugeObject)
- as long as SomeHugeObject doesn't have a destructor, copy constructor or copy assignment operator the default move constructor will be called. Otherwise SomeHugeObject will need to define a move constructor and move assignment operator.
I believe these should be all the possible instances where const can be used. (Obviously they can be used in combination as well.)
Mainly are the things I've written under the since c++11 accurate? Are there any other times when const should be used or when c++11 has changed the meaning of something due to the move semantics?
C++ Checking if a character is not in a string with || not working
I am working on this game where the player gets asked to play again. I am used to checking if a condition is not met and then return false, so at the end I can simply add return true. This also helps with nesting.
If I do it the other way around it works:
bool AskToPlayAgain() {
cout << "Do you want to play again? ";
string Response = "";
getline(cin, Response);
if (Response[0] == 'y' || Response[0] == 'Y')
{
cout << "True!\n";
return true;
}
cout << "False!\n";
return false;
}
This will return true on y and Y, and False on every other character.
However. The way I want it is like this:
if (Response[0] != 'y' || Response[0] != 'Y')
{
cout << "False!\n";
return false;
}
cout << "True!\n";
return true;
Only, no matter the response, it will always validate to false. Why is that? And how can I fix it?
How to use generic template function to handle objects with different members?
I have looked around a while for a solution to this, however, I might not know the exact definition or language syntax of what I am trying to accomplish, so I decided to post.
I have certain objects/structs like so:
struct A
{
char myChar;
bool hasArray = false;
};
template <uint8_t ARRAY_LEN>
struct AA : public A
{
hasArray = true;
uint8_t myArray[ARRAY_LEN];
};
I want to create a generic function that can take in both of these object types and to perform common work as well as specific work for the derived struct AA
. Something like the following:
template <typename T>
void func(T (&m))
{
if (T.hasArray)
{
// do some processing with m.myArray
std::cout << sizeof(m.myArray) << std::endl;
// ...
}
// common processing
std::cout << "myChar: " << m.myChar << std::endl;
};
I want to be able to call the function like so:
A a;
AA aa;
func(a); // compiler error, this would not work as no array member
func(aa); // this works
Granted this is just an example that illustrates my intent, but it sums up what I would like to do. The actual code is a lot more complex and involved many more objects. I know I can overload, but I want to know if there is a way to do it with one generic function? Also note that I understand why the compiler complains with the sample code I would like to know if there is a workaround or some other c++ functionality that I am missing. I would not like to do any type casting... - Using c++11 and GCC 4.8.5
Does std::future spin-wait?
Before explaining the question in more detail, I'll note that the answer is obviously implementation dependent, so I'm primarily asking about libstdc++, but I would also be interested in hearing about libc++. The operating system is Linux.
Calling wait()
or get()
on a std::future
blocks until the result is set by an asynchronous operation -- either an std::promise
, std::packaged_task
, or std::asyn
function. The availability of the result is communicated through a shared state, which is basically an atomic variable: the future waits for the shared state to be marked as ready by the promise (or async task). This waiting and notification is implemented in libstdc++ via a futex system call. Granted that futexes are highly performant, in situations where a future expects to only wait for an extremely brief period (on the order of single microseconds), it would seem that a performance gain could be made by spinning on the shared state for a short time before proceeding to wait on the futex.
I have not found any evidence of such spinning in the current implementation, however, I did find a comment in atomic_futex.h at line 161 where I would expect to find such spinning:
// TODO Spin-wait first.
So my question is rather the following: Are there really plans to implement a spin-wait, and if so, how will the duration be decided? Additionally, is this the type of functionality that could eventually be specified through a policy to the future?
C++ std::string to number template
I am currently trying to implement my own standard input reader for personal use. I have created a method to read an integer from std input and do some checks on its validity. The idea is that I read a string from the std input, do several checks, convert to int, do last checks, return the value that has been read. If any error happens meanwhile the checks I will just fill an errorHint to print on std::cerr and return std::numeric_limits::min().
I think the idea is quite simple and straightforward to implement, now I wanted to generalise the concept and make the method template, so basically I could chose at compile time, whenever I need to read from the std input which type of integer I want (it could be int, long, long long, unsigned long and so on but an integer). In order to do so I have created the following static template method:
template<
class T,
class = typename std::enable_if<std::is_integral<T>::value, T>::type
>
static T getIntegerTest(std::string& strErrorHint,
T nMinimumValue = std::numeric_limits<T>::min(),
T nMaximumValue = std::numeric_limits<T>::max());
and the implementation in the same .hpp file few lines below:
template<
class T,
class>
T InputReader::getIntegerTest(std::string& strErrorHint,
T nMinimumValue,
T nMaximumValue)
{
std::string strInputString;
std::cin >> strInputString;
// Do several checks
T nReturnValue = std::stoi(strInputString); /// <--- HERE!!!
// Do other checks on the returnValue
return nReturnValue;
}
Now the problem is, I want to convert the string that I just read and that I know is within the correct range to the integer type T. How can I do this in a good way?
How standards-compliant is my polymorph?
Often in code I write there are types that are layout-compatible but are distinct types, but still I'd like to pass them around as if they were the same type. This comes with quite some syntactical overhead, including the necessary casts etc.
I (very) recently thought up a small helper mix-in class, which I dubbed polymorph
:
struct polymorph
{
template<typename T>
const T& as() const { return static_cast<const T&>(*this); }
template<typename T>
T& as() { return static_cast<const T&>(*this); }
}
My question is: how robust is this class, and how could I make this more resilient against misuse and/or undefined behaviour. I haven't used it a lot and am kind of hesitant because there are a lot of things that could go terribly wrong.
This class is primarily intended for correspondences such as the one between _Complex
/std::complex<double>
/double[2]
. I'm still thinking of a nice way to extend it to perform useful conversions, and exactly how useful that could be.
C++ Dynamic Arrays Index and Capacity problems
My home work is to ask me to build a dynamic array and with other functions. I've managed to complete the rest of the problems but there is one bug I don't understand...
Currently if I set D[0]=11
and D[1]=12
, no matter how big the array is, all values in the array will turned into 12, along with the capacity with it will become 12.
These are the codes I think is relevant below, I will provide more per request.
template <class dynElem>
class dynarr {
private:
int capacity;
dynElem *A;
public:
dynarr() : capacity(0), A(NULL){};
dynarr(int N): capacity(N), A(new dynElem[N]){}
dynarr(const dynarr<dynElem> &other);
~dynarr();
dynarr<dynElem> & operator=( const dynarr<dynElem> &other);
dynElem & operator[](int ndx) throw(InvalidIndex);
int getCapacity();
void reserve(int newcap);
};
template <class dynElem>
dynarr<dynElem>::dynarr(const dynarr<dynElem> &other)
{
capacity = other.capacity;
A = new dynElem[capacity];
for (int i = 0; i < other.capacity; i++) {
A[i] = other.A[i];
}
}
template <class dynElem>
dynarr<dynElem>::~dynarr()
{
delete[] A;
}
test.cpp
int main()
{
dynarr<int> D(15);
std::cout << "The capacity of D is " << D.getCapacity() << std::endl;
D[0] = 11;
D[1] = 12;
std::cout << "D[0] = " << D[0] << std::endl; //12
std::cout << "D[1] = " << D[1] << std::endl; //12
std::cout << "The capacity of D is " << D.getCapacity() << std::endl; //12
return 0;
}
Strange behaviour in atexit()
Let's suppose we have the following (bad) code which does stuff at exit:
//Singleton class Test
class Test{
public:
static Test& getTest(){
static Test t;
return t;
}
void addElement(std::string s){
list[index] = s;
index++;
}
void print(){
for(int i = 0; i < index; i++){
cout << list[i] << endl;
}
}
private:
int index = 0;
std::array<std::string, 30> list;
};
//Function called at exit
void onExit(){
Test::getTest().addElement("Another one");
Test::getTest().print();
}
//...and main
int main()
{
std::atexit(onExit);
Test::getTest().addElement("String");
return 0;
}
The first time I saw this I expected the following output:
String
Another one
But strangely it prints
Another one
Another one
Is there something I am missing? Does the array get cleared and filled...twice?
Objects of non-movable classes not throwable?
When compiled with Clang 3.9.1 or GCC 6.3.0 throwing movable but not copyable objects seems to work fine:
struct MovableNonCopyable {
MovableNonCopyable();
~MovableNonCopyable();
MovableNonCopyable(MovableNonCopyable &&);
MovableNonCopyable(MovableNonCopyable const &) = delete;
MovableNonCopyable & operator=(MovableNonCopyable &&);
MovableNonCopyable & operator=(MovableNonCopyable const &) = delete;
};
void f() { throw MovableNonCopyable(); }
But throwing copyable but not movable objects like this:
struct CopyableNonMovable {
CopyableNonMovable();
~CopyableNonMovable();
CopyableNonMovable(CopyableNonMovable &&) = delete;
CopyableNonMovable(CopyableNonMovable const &);
CopyableNonMovable & operator=(CopyableNonMovable &&) = delete;
CopyableNonMovable & operator=(CopyableNonMovable const &);
};
void g() { throw CopyableNonMovable(); }
instead causes compilation error like:
test.cpp: In function 'void g()':
test.cpp:21:41: error: use of deleted function 'CopyableNonMovable::CopyableNonMovable(CopyableNonMovable&&)'
void g() { throw CopyableNonMovable(); }
^
test.cpp:15:9: note: declared here
CopyableNonMovable(CopyableNonMovable &&) = delete;
^~~~~~~~~~~~~~~~~~
Why is this? According to [except.throw#5] this should be the other way around, i.e. the copy constructor should be accessible.
Is it possible to ensure a constexpr function is called at most once at compile time?
As the title asks: Is it possible to ensure a constexpr function is called at most once at compile time?
This clearly won't be possible if the function is not constepxr; I could write a function that gets called whenever I press the space bar, so the compiler could never figure that out at compile time.
Impossible implicit move operations?
As far as I understand [class.copy.ctor] and [class.copy.assign], struct A
in the following code should not be move-constructible nor move-assignable:
#include <type_traits>
struct X {
X() noexcept; // user-declared default constructor
~X() noexcept; // Force X not to be trivially copyable
X(X &&) = delete; // Explicitly deleted move constructor
X(X const &) = delete; // Explicitly deleted copy constructor
X & operator=(X &&) = delete; // Explicitly deleted move assignment operator
X & operator=(X const &) = delete; // Explicitly deleted copy assignment op.
};
static_assert(!std::is_copy_constructible<X>::value, "");
static_assert(!std::is_copy_assignable<X>::value, "");
static_assert(!std::is_move_assignable<X>::value, "");
static_assert(!std::is_move_constructible<X>::value, "");
static_assert(!std::is_trivially_copyable<X>::value, "");
static_assert(!std::is_trivially_copy_assignable<X>::value, "");
static_assert(!std::is_trivially_copy_constructible<X>::value, "");
static_assert(!std::is_trivially_move_assignable<X>::value, "");
static_assert(!std::is_trivially_move_constructible<X>::value, "");
struct A {
A() noexcept; // user-declared default constructor
A(A const &) noexcept; // user-declared copy constructor
A & operator=(A const &) noexcept; // user-declared copy assignment operator
X x;
};
static_assert(std::is_copy_constructible<A>::value, "");
static_assert(std::is_copy_assignable<A>::value, "");
static_assert(!std::is_move_assignable<A>::value, ""); // FAILS?!
static_assert(!std::is_move_constructible<A>::value, ""); // FAILS?!
static_assert(!std::is_trivially_copyable<A>::value, "");
static_assert(!std::is_trivially_copy_assignable<A>::value, "");
static_assert(!std::is_trivially_copy_constructible<A>::value, "");
static_assert(!std::is_trivially_move_assignable<A>::value, "");
static_assert(!std::is_trivially_move_constructible<A>::value, "");
However, two of the static assertions fail with both GCC and Clang, which mean that for some reason A
is move-assignable and move-constructible.
In my reasoning this shouldn't be, because struct A
:
- does not explicitly declare a move constructor
- does not explicitly declare a move assignment operator
- has a user-declared copy constructor
- has a user-declared copy assignment operator.
- has a field
x
of typeX
which is can not be direct-initialized with any otherA::x
, because all constructors ofX
which would participate in overload resolution for this are explicitly deleted.
Is this a compiler bug or am I misunderstanding something?
Building a Templated Container Class
As a part of my custom object system I would like to have a Container class that just wraps a third party object so that they can be integrated into my container system.
Assuming I have the following third party object,
class Point {
public:
int x;
Point(int y = 0) : x(y) {}
int value() { return x; }
};
Container class,
template <typename T, typename... Args> class Value{
T dat;
public:
Container(const Args &... args) { dat = T(args...); }
T data() { return dat; }
};
I am trying to provide the following api,
Value<Point> v = Value<Point>(1);
I am trying to pass the parameters passed to the value constructor directly to type T constructor.
c++ template specialization, error when using typename
I need to specialized a member function:
template <typename T>
int32_t writeVectorVariableUnit(
foo& classFoo,
typename std::vector<T>::const_iterator& start,
typename std::vector<T>::const_iterator& stop,
const std::string& name,
const std::string& unit,
const std::string& longName,
const std::vector<std::string>& dimName) const
in this way:
template <>
int32_t writeVectorVariableUnit(
foo& classFoo,
std::vector<uint16_t>::const_iterator& start,
std::vector<uint16_t>::const_iterator& stop,
const std::string& name,
const std::string& unit,
const std::string& longName,
const std::vector<std::string>& dimName) const;
but the g++ compiler (version 4.4.7 on a redhat 6.7) complains that is not able to match any template declaration:
error: template-id ‘writeVectorVariableUnit<>’ for ‘int32_t writeVectorVariableUnit(foo&, __gnu_cxx::__normal_iterator > >&, __gnu_cxx::__normal_iterator > >&, const std::string&, const std::string&, const std::string&, const std::vector, std::allocator >, std::allocator, std::allocator > > >&) const’ does not match any template declaration
I suspect that is related with the usage of typename, I try several combination without success. Do you have any suggestion?
Thanks in advance
How to get class type in class scope with a macro without any arguments?
Is it possible to get the class type
struct A{
DEFINE_CLASS_NAME();
};
such that there is a type A::Type
which is A
again. Restrictions the macro DEFINE_CLASS_NAME
should not have ANY Argument. This is a hypothetical question, if it is possible to access the type in class scope with declval and decltype somehow...
How to call a request to a server with period ans send it again if response was invalid
I'm writting a simple client for a web service for my personal training. And i decided to do it with Qt. I'm using version 5.7. I managed to overcome troubles with sending and recieving requests from a server. But there is still a problem.
I have a slot on_scanButton_click() which, depending on what radio button is checked calls some request to a server. My problem is how to send another request to a server after first one with a period so that i could check if response_code in valid and i can call separate window for it.
This is my mainwindow.cpp
#include "mainwindow.h"
#include "networkmanager.h"
#include "commentdialog.h"
#include "rescanfiledialog.h"
#include "filebrowser.h"
#include "program_exceptions.h"
#include "overlaywidget.h"
#include <QMessageBox>
#include <regex>
MainWindow::MainWindow(QWidget* parent) :
QMainWindow{parent} {
ui.setupUi(this);
ui.fileRadioButton->setFixedWidth(100);
ui.urlRadioButton->setFixedWidth(100);
ui.searchRadioButton->setFixedWidth(100);
ui.stringFormater->setFixedSize(500, 30);
ui.stringFormater->setPlaceholderText("No file selected");
ui.uploadButton->setFixedHeight(30);
ui.scanButton->setFixedSize(120, 50);
ui.rescanButton->setFixedSize(120, 50);
ui.commentButton->setFixedSize(120, 50);
}
void MainWindow::changeEvent(QEvent* e) {
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui.retranslateUi(this);
break;
default:
break;
}
}
void MainWindow::on_scanButton_clicked() {
NetworkManager* network_manager{new NetworkManager};
QString input_string = ui.stringFormater->text();
try {
if (ui.fileRadioButton->isChecked()) {
if (std::regex_match(input_string.toStdString(), std::regex("^(.*/)([^/]*)$"))) {
network_manager->scanFileRequest(input_string);
} else {
throw InvalidFilePathException();
}
} else if (ui.urlRadioButton->isChecked()) {
if (std::regex_match(input_string.toStdString(),
std::regex("^(ht{2}ps?:\\/{2})?(w{3}\\.)?([^:\\/\\.\\s]+)\\.([^:\\/\\.\\s]+)$"))) {
network_manager->scanUrlRequest(input_string);
} else {
throw InvalidUrlNameException();
}
} else if (ui.searchRadioButton->isChecked()) {
if (!std::regex_match(input_string.toStdString(), std::regex("([^:\\/\\.\\s]+)\\.([^:\\/\\.\\s]+)$"))) {
if (!std::regex_match(input_string.toStdString(), std::regex("^(([0-9]{1,3})\\.){3}([0-9]{1,3})$"))) {
throw InvalidIpAddressException();
} else {
network_manager->retrieveIpReportRequest(input_string);
}
throw InvalidDomainNameException();
} else {
network_manager->retrieveDomainReportRequest(input_string);
}
}
} catch (std::exception& ex) {
QString exception_message{ex.what()};
QMessageBox::warning(this, "Warning", exception_message);
}
ui.stringFormater->clear();
}
void MainWindow::on_fileRadioButton_clicked() {
ui.stringFormater->setPlaceholderText("No file selected");
ui.uploadButton->setText("Choose File");
ui.scanButton->setText("Scan it!");
ui.stringFormater->clear();
}
void MainWindow::on_urlRadioButton_clicked() {
ui.stringFormater->setPlaceholderText("http://example.com");
ui.uploadButton->setText("Enter URL");
ui.scanButton->setText("Scan it!");
ui.stringFormater->clear();
}
void MainWindow::on_searchRadioButton_clicked() {
ui.stringFormater->setPlaceholderText("hash, URL, domain, IP address...");
ui.uploadButton->setText("Enter Term");
ui.scanButton->setText("Search it!");
ui.stringFormater->clear();
}
void MainWindow::on_uploadButton_clicked() {
if (ui.fileRadioButton->isChecked()) {
FileBrowser* file_browser{new FileBrowser(this)};
file_browser->exec();
ui.stringFormater->setText(file_browser->getFilePath());
file_browser->setFilePath("");
}
}
void MainWindow::on_rescanButton_clicked() {
RescanFileDialog* rescan_file_doalog{new RescanFileDialog(this)};
rescan_file_doalog->exec();
}
void MainWindow::on_commentButton_clicked() {
CommentDialog* comment_dialog{new CommentDialog(this)};
comment_dialog->exec();
}
Here goes networkmanager.h.
#ifndef NETWORKMANAGER_H
#define NETWORKMANAGER_H
#include <QtNetwork>
class NetworkManager : public QObject {
Q_OBJECT
private:
QString api_address{"http://ift.tt/2kJzNZo"};
QByteArray api_key{"API KEY HERE"};
QNetworkAccessManager* network_manager{new QNetworkAccessManager(this)};
static QJsonObject json_response;
public:
explicit NetworkManager() {
connect(network_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
}
virtual ~NetworkManager() = default;
void scanFileRequest(const QString&);
void rescanFileRequest(const QString&);
void retrieveFileReportRequest(const QString&);
void scanUrlRequest(const QString&);
void retrieveUrlReportRequest(const QString&);
void retrieveIpReportRequest(const QString&);
void retrieveDomainReportRequest(const QString&);
void makeCommentRequest(const QString&, const QString&);
const static QJsonObject getJsonResponse() {
return json_response;
}
private slots:
void requestFinished(QNetworkReply*);
};
#endif // NETWORKMANAGER_H
And networkmanager.cpp.
#include "networkmanager.h"
#include "responses.h"
#include "status_codes.h"
#include "program_exceptions.h"
#include <QMessageBox>
#include <QTimer>
QJsonObject NetworkManager::json_response{};
void NetworkManager::scanFileRequest(const QString& absolute_file_path) {
const QFileInfo file_info{absolute_file_path};
QHttpMultiPart* multi_part{new QHttpMultiPart(QHttpMultiPart::FormDataType)};
QHttpPart api_key_part{};
api_key_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"apikey\""));
api_key_part.setBody(api_key);
QHttpPart file_part{};
QMimeDatabase db{};
QMimeType mime_message{db.mimeTypeForFile(file_info)};
file_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(mime_message.name()));
file_part.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"file\"; filename=\"" + file_info.fileName() + "\""));
QFile* file{new QFile(absolute_file_path)};
try {
if (!file->open(QIODevice::ReadOnly)) {
throw FileDoesNotExistException();
}
} catch (std::exception& ex) {
QMessageBox message_box{QMessageBox::Warning, "Warning", QObject::tr(ex.what()),
QMessageBox::NoButton, 0, Qt::FramelessWindowHint};
message_box.exec();
}
file_part.setBodyDevice(file);
file->setParent(multi_part);
multi_part->append(api_key_part);
multi_part->append(file_part);
QNetworkRequest request{QUrl{api_address + "/file/scan"}};
network_manager->post(request, multi_part);
}
void NetworkManager::rescanFileRequest(const QString& resource) {
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("resource", resource);
QUrl post_params{};
post_params.setQuery(query_set);
QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
post_data.remove(0, 1);
QNetworkRequest request{QUrl{api_address + "/file/rescan"}};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_manager->post(request, post_data);
}
void NetworkManager::retrieveFileReportRequest(const QString& resource) {
QUrl url{api_address + "/file/report"};
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("resource", resource);
url.setQuery(query_set.query());
QNetworkRequest request{url};
network_manager->get(request);
}
void NetworkManager::scanUrlRequest(const QString& url) {
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("url", url);
QUrl post_params{};
post_params.setQuery(query_set);
QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
post_data.remove(0, 1);
QNetworkRequest request{QUrl{api_address + "/url/scan"}};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_manager->post(request, post_data);
}
void NetworkManager::retrieveUrlReportRequest(const QString& resource) {
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("resource", resource);
QUrl post_params{};
post_params.setQuery(query_set);
QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
post_data.remove(0, 1);
QNetworkRequest request{QUrl{api_address + "/url/report"}};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_manager->post(request, post_data);
}
void NetworkManager::retrieveIpReportRequest(const QString& ip) {
QUrl url{api_address + "/ip-address/report"};
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("ip", ip);
url.setQuery(query_set.query());
QNetworkRequest request{url};
network_manager->get(request);
}
void NetworkManager::retrieveDomainReportRequest(const QString& domain) {
QUrl url{api_address + "/domain/report"};
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("domain", domain);
url.setQuery(query_set.query());
QNetworkRequest request{url};
network_manager->get(request);
}
void NetworkManager::makeCommentRequest(const QString& resource, const QString& comment) {
QUrlQuery query_set{};
query_set.addQueryItem("apikey", api_key);
query_set.addQueryItem("resource", resource);
query_set.addQueryItem("comment", comment);
QUrl post_params{};
post_params.setQuery(query_set);
QByteArray post_data{post_params.toEncoded(QUrl::RemoveFragment)};
post_data.remove(0, 1);
QNetworkRequest request{QUrl{api_address + "/comments/put"}};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_manager->post(request, post_data);
}
void NetworkManager::requestFinished(QNetworkReply* reply) {
try {
http_status_code_t server_reply{static_cast<http_status_code_t>(
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt())};
if (server_reply == OK) {
QJsonObject json_object = QJsonDocument::fromJson(reply->readAll()).object();
response_code_t response_code{static_cast<response_code_t>(json_object["response_code"].toInt())};
std::string verbose_msg{json_object["verbose_msg"].toString().toStdString()};
if (response_code == ITEM_IS_PRESENT) {
json_response = json_object;
qDebug() << json_response;
} else if (response_code == ITEM_IS_STILL_IN_QUEUE) {
throw RequestStillInQueueException(verbose_msg);
} else if (response_code == ITEM_DOES_NOT_EXIST) {
throw ItemDoesNotExistException(verbose_msg);
} else {
throw UnknownResponseCodeException();
}
} else if (server_reply == API_REQUEST_LIMIT_EXCEEDED) {
throw PublicAPIRequestRateExceededException();
} else if (server_reply == FORBIDDEN) {
throw ForbiddenException();
} else {
throw UnknownHttpStatusCodeException();
}
} catch (std::exception& ex) {
QMessageBox message_box{QMessageBox::Warning, "Warning", QObject::tr(ex.what()),
QMessageBox::NoButton, 0, Qt::FramelessWindowHint};
message_box.exec();
}
}
So the question is where i have to put my QTimer, which will send retireveXXXXRequest() function every 15 seconds till it gets response code what i need.
Generic static method
Hello I am trying to create a static method for checking null pointers in Unreal Engine.
.h file
template<typename T>
static bool checkForNull(T pointer);
.cpp file
bool MyClass::checkForNull(T pointer)
{
{
if (!pointer) {
printlog(FString("Your pointer is null")); //Another static function for printing
return false;
}
else {
return true;
}
}
}
But I am also new to C++ and I think there is a syntax error in my code? How can I create a static generic method?
double free or corruption with dynamic arrays
my problem today is with dynamic arrays. Every time I enter more then 2 test scores I get an error after I enter the 3rd max test score which says "* Error in `./a.out': double free or corruption (out): 0x09c2e028 * Aborted (core dumped)" Am I doing something wrong with the arrays? Or is there something I'm painfully missing?
The program is supposed to take an unlimited number of test scores and their respective max possible points (i.e. test score = 76 Max test score possible = 100) and turn those numbers into a GPA. I'be only included the class I'm using to create the GPA because the rest of the code isn't finished yet as I can't get past this part.
I have to use the dynamic arrays because it is for a school assignment.
Thanks for reading I hope someone can help me!
#include <iostream>
#include <string>
#include <cmath>
#include <math.h>
#include <iomanip>
#include <cassert>
using namespace std;
void programGreeting();
class testScores{
public:
float testAverage(){
int i = 0;
float gpa2 = 0;
int loopCountVar = 0;
int size = 1;
int size2 = 1;
float *testScore = new float[size];
float *maxScore = new float[size];
while(testScore[i] != -1){
i++;
loopCountVar++;
cout << "Enter test score #" << loopCountVar << endl;
cin >> testScore[i];
if(testScore[i] == -1){
size = i;
}
assert(testScore[i] > -2);
cout << "Enter max test score #" << loopCountVar << endl;
cin >> maxScore[i];
if(maxScore[i] == -1){
size2 = i;
}
assert(maxScore[i] > -2);
}
float *gpa = new float[size];
for(i = 1; i < size; i++){
gpa[i] = testScore[i] / maxScore[i];
cout << gpa[i] << " " << endl;
}
for(i = 1; i < size; i++){
gpa2 += gpa[i];
}
for (i = 1; i < size; i++){
cout << endl << testScore[i] << " " << endl;
}
for (i = 1; i < size2; i++){
cout << endl << maxScore[i] << " ";
}
cout << endl << gpa2 << endl;
cin >> size;
delete testScore;
delete [] maxScore;
delete gpa;
return 0;
}
};
How to check if every type in a parameter pack is unique?
For a fixed number of template parameters it is easy, although the number of manually written checks grows quadratically.
#include <type_traits>
template <
typename T1,
typename T2,
typename T3,
typename T4>
struct unique_types
{
static_assert(!std::is_same<T1, T2>::value, "Types must be unique");
static_assert(!std::is_same<T1, T3>::value, "Types must be unique");
static_assert(!std::is_same<T1, T4>::value, "Types must be unique");
static_assert(!std::is_same<T2, T3>::value, "Types must be unique");
static_assert(!std::is_same<T2, T4>::value, "Types must be unique");
static_assert(!std::is_same<T3, T4>::value, "Types must be unique");
};
int main()
{
// OK.
unique_types<int, double, char, float> foo;
// Should not compile.
unique_types<int, double, char, double> bar;
}
How could this be implemented for a parameter pack with an arbitrary number of types?
dimanche 29 janvier 2017
How to Instantiate my code utilizing C++11 unique_ptr?
In my experimental game engine I'm currently creating some game sub-systems out on the heap with raw pointers. Basically, my derived classes use their constructors to call a protected constructor within base which news up these sub-systems for them. My code for this is like so:
Entity.h (Base class)
#pragma once
#include <memory>
namespace BlazeGraphics{ class Graphics; }
namespace BlazePhysics{ class Physics; }
namespace BlazeInput{ class Controller; }
namespace BlazeGameWorld
{
class Entity
{
protected:
Entity(BlazeGraphics::Graphics* renderer, BlazePhysics::Physics* physics, BlazeInput::Controller* controller);
BlazeGraphics::Graphics* renderer;
BlazePhysics::Physics* physics;
BlazeInput::Controller* controller;
};
}
Entity.cpp
#include "Graphics/Graphics.h"
#include "Input/Controller.h"
#include "Physics/Physics.h"
#include "Input/Input.h"
#include "Entity.h"
namespace BlazeGameWorld
{
Entity::Entity()
{}
Entity::Entity(BlazeGraphics::Graphics* renderer, BlazePhysics::Physics* physics, BlazeInput::Controller* controller) :
renderer(renderer),
physics(physics),
controller(controller),
position(0.0f, 0.0f),
velocity(0.0f, 0.0f)
{
}
Entity::~Entity()
{
}
}
Player.cpp (Derived)
#include "Graphics/Graphics.h"
#include "Input/Input.h"
#include "Input/PlayerController.h"
#include "Physics/Physics.h"
#include "Player.h"
namespace BlazeGameWorld
{
Player::Player() :
Entity(new BlazeGraphics::Graphics, new BlazePhysics::Physics, new BlazeInput::PlayerController)
{
}
Player::~Player()
{
}
}
How would I update() this code to properly utilize C++11's unique_ptr? I'm having trouble figuring out how to initialize this smart ptr properly in my classes.
regex match c++
What is a simple way to return a string that matches a regex in C++11? Example:
"The great brown fox jumped over the lazy dog."
/g[a-z]+/
Returns: "great"
Error request for member 'str' in 'c', which is of non-class type
this is the .hpp file for which i had written implementation still having errors please help me solve them thank you in advance.
#ifndef STORE_HPP
#define STORE_HPP
#include<string>
#include "Customer.hpp"
class Store
{
private:
std::vector<std::string> inventory;
std::vector<std::string> members;
public:
void addProduct(Product* p);
void addMember(Customer* c);
Product* getProductFromID(std::string);
Customer* getMemberFromID(std::string);
void productSearch(std::string str);
void addProductToMemberCart(std::string pID, std::string mID);
void checkOutMember(std::string mID);
};
#endif
this is the .cpp file some methods are having errors please solve them thankyou in advance
#include <iostream>
#include <string.h>
#include "Customer.hpp"
#include "Store.hpp"
#include "Product.hpp"
using namespace std;
string id;
void Store::addProduct(Product* p)
{
Product p(std::string id, std::string t, std::string d, double p, int qa);
inventory.push_back(id);
}
void Store:: addMember(Customer* c)
{
Customer c(std::string n, std::string a, bool pm);
members.push_back(c.str());
}
std::String Store:: Product* getProductFromID(std::string id)
{
for(int i = 0; i < inventory.size(); i++)
{
Product* p=inventory.at(i);
if(p->getProductFromID(id) == id)
{
return p;
}
}
return NULL;
}
std::String Store:: Customer* getMemberFromID(std::string id)
{
for(int i = 0; i < members.size(); i++)
{
Customer* c = members.at(i);
if(c->getAccountID() == id)
{
return c;
}
}
return NULL;
}
void std::Store productSearch(std::string str)
{
for(int i = 0; i < inventory.size(); i++)
{
if(inventory[i] == str)
{
Product stud(inventory[i],inventory[i+1],inventory[i+2],inventory[i+3],inventory[i+4]);
cout<<getIdCode();
cout<<getTitle();
cout<<getDescription();
cout<<getPrice();
cout<<getQuantityAvailable();
}
}
}
void addProductToMemberCart(std::string pID, std::string mID)
{
cout<<"adding to cart"<<endl;
getMemberFromID(mID)->addProductToCart(pID);
}
void checkOutMember(std::string mID)
{
Customer* c=getAccountID(mID)
mID=getMemberFromID(std::string mID);
if(mID=="NULL")
{
cout<<mID<<"is not found"<<endl;
}
}
this is the customer.hpp file
#ifndef CUSTOMER_HPP
#define CUSTOMER_HPP
#include<vector>
#include "Product.hpp"
class Customer
{
private:
std::vector<std::string> cart;
std::string name;
std::string accountID;
bool premiumMember;
public:
Customer(std::string n, std::string a, bool pm);
std::string getAccountID();
//std::vector getCart();
void addProductToCart(std::string);
bool isPremiumMember();
void emptyCart();
};
#endif
this is the .cpp file for the customer
#include <iostream>
#include <string>
#include <vector>
#include "Customer.hpp"
using namespace std;
string accountID;
bool premiumMember;
Customer::Customer(std::string n, std::string a, bool pm)
{
name=n;
accountID=a;
premiumMember=pm;
}
std::string Customer:: getAccountID()
{
return accountID;
}
void Customer:: addProductToCart(std::string accountID)
{
cart.push_back(accountID);
}
bool Customer:: isPremiumMember()
{
return premiumMember;
}
/*vector Customer::getCart()
{
return std::cart;
}*/
void Customer:: emptyCart()
{
cart.clear();
}
this is the product.hpp file
#ifndef PRODUCT_HPP
#define PRODUCT_HPP
#include<vector>
class Product
{
private:
std::string idCode;
std::string title;
std::string description;
double price;
int quantityAvailable;
public:
Product(std::string id, std::string t, std::string d, double p, int qa);
std::string getIdCode();
std::string getTitle();
std::string getDescription();
double getPrice();
int getQuantityAvailable();
void decreaseQuantity();
};
#endif
this is the .cpp file for product.hpp
#include<iostream>
#include<string>
#include "Product.hpp"
using namespace std;
string idCode;
string title;
string description;
double price;
int quantityAvailable;
Product::Product(std::string id, std::string t, std::string d, double p, int qa)
{
idCode=id;
title=t;
description=d;
price=p;
quantityAvailable=qa;
}
std::string Product:: getIdCode()
{
return idCode;
}
std::string Product::getTitle()
{
return title;
}
std::string Product::getDescription()
{
return description;
}
double Product::getPrice()
{
return price;
}
int Product::getQuantityAvailable()
{
return quantityAvailable;
}
C++11 scoping and lifetime of temporary bound to a (const) reference (GCC)
I have the following questions related to the same situation (not in general):
- Why does the compiler not produce a warning when a temporary is bound to a reference?
- How does lifetime extension of a temporary work (when it is bound to a reference)?
- How to interpret / understand the C++ standard (C++11)?
- Is this a bug (in the compiler)? Should it be?
So this is what we are talking about:
struct TestRefInt {
TestRefInt(const int& a) : a_(a) {};
void DoSomething() { cout << "int:" << a_ << endl; }
protected:
const int& a_;
};
Should TestRefInt tfi(55);
and tfi.DoSomething();
work? How and where? So here is a code
TestRefInt tfi(55);
int main() {
TestRefInt ltfi(8);
tfi.DoSomething();
ltfi.DoSomething();
return 0;
}
What should this do?
Here I will elaborate some more.
Consider this real world (simplified) example. How does it look like to a novice/beginner C++ programmer? Does this make sense?
(you can skip the code the issue is the same as above)
#include <iostream>
using namespace std;
class TestPin //: private NonCopyable
{
public:
constexpr TestPin(int pin) : pin_(pin) {}
inline void Flip() const {
cout << " I'm flipping out man : " << pin_ << endl;
}
protected:
const int pin_;
};
class TestRef {
public:
TestRef(const TestPin& a) : a_(a) {};
void DoSomething() { a_.Flip(); }
protected:
const TestPin& a_;
};
TestRef g_tf(1);
int main() {
TestRef tf(2);
g_tf.DoSomething();
tf.DoSomething();
return 0;
}
Command line:
/** Compile:
Info: Internal Builder is used for build
g++ -std=c++11 -O0 -g3 -Wall -Wextra -Wconversion -c -fmessage-length=0 -o "src\\Scoping.o" "..\\src\\Scoping.cpp"
g++ -o Scoping.exe "src\\Scoping.o"
13:21:39 Build Finished (took 346ms)
*/
Output:
/**
I'm flipping out man : 2293248
I'm flipping out man : 2
*/
The issue: TestRef g_tf(1); /// shouldn't the reference to temporary extend it's life in
global scope too?
What does the standard says?
From How would auto&& extend the life-time of the temporary object?
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself
^^^^^
Globals are not allocated on stack, so lifetime is not extended. However, the compiler does not produce any warning message whatsoever! Shouldn’t it at least do that?
But my main point is: from a usability standpoint (meaning as the user of C++, GCC as a programmer) it would be useful if the same principle would be extended to not just stack, but to global scope, extending the lifetime (making global temporaries “permanent”).
Sidenote: The problem is further complicated by the fact that the TestRef g_tf(1);
is really TestRef g_tf{ TestPin{1} };
but the temporary object is not visible in the code, and without looking at the constructor declaration it looks like the constructor is called by an integer, and that rarely produces this kind of error.
As far as I know the only way to fix the problem is to disallow temporaries in initialization by deleting TestRefInt(const int&& a) =delete;
constructor. But this also disallows it on stack, where lifetime extension worked.
But the previous quote is not exactly what the C++11 standard say. The relevant parts of the C++11 Standard are 12.2 p4 and p5:
4 - There are two contexts in which temporaries are destroyed at a different point than the end of the full expression. The first context is [...]
5 - The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
— A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
— A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call. § 12.2 245 c ISO/IEC N3337
— The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
— A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer. [Example: struct S { int mi; const std::pair& mp; }; S a { 1, {2,3} }; S* p = new S{ 1, {2,3} }; // Creates dangling reference — end example ] [ Note: This may introduce a dangling reference, and implementations are encouraged to issue a warning in such a case. — end note ]
My English and understanding of the standard is not good enough, so what exception is this? The “— A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.” or “reference parameter in a function call” does not mention anything about allocation on stack or in global scope. The other exceptions do not seem to apply. Am I wrong?
Which one is this, or none of them?
We have a temporary in a function call (the constructor) and then a reference to the temporary is bound to a member reference in the initializer. Is this undefined behavior? Or the exception still applies, and the temporary should be destroyed? (or both)
What about this?
struct TestRefIntDirect {
TestRefIntDirect(int a) : a_(a) {};
void DoSomething() { cout << "int:" << a_ << endl; }
protected:
const int& a_;
};
One less reference, same behavior.
Why does it work in one case (instantiation inside a function) versus in other case (in global scope)?
Does GCC not “destroy” one of them by “accident”?
My understanding is that none of them should work, the temporary should not persist as the standard says. It seems GCC just "lets" you access not persisting objects (sometimes). I guess that the standard does not specify what the compiler should warn about, but can we agree that it should? (in other cases it does warn about ‘returning reference to temporary’) I think it should here too.
Is this a bug or maybe there should be a feature request somewhere?
It seems to me like GCC says “Well, you shouldn’t touch this cookie, but I will leave it here for you and not warn anyone about it.” ...which I don’t like.
This thing others reference about stack I did not find in the standard, where is it coming from? Is this misinformation about the standard? Or is this a consequence of something in the standard? (Or is this just implementation coincidence, that the temporary is not overwritten and can be referenced, because it happened to be on the stack? Or is this compiler defined behavior, extension?)
The more I know C++ the more it seems that every day it is handing me a gun to shoot myself in the foot with it…
I would like to be warned by the compiler if I’m doing something wrong, so I can fix it. Is that too much to ask?
Other related posts:
C++: constant reference to temporary
Does a const reference prolong the life of a temporary?
Returning temporary object and binding to const reference
I didn’t want to write this much. If you read it all, thanks.
Why my code is not working and showing Segmentation Fault error?
#include <iostream>
using namespace std;
int main() {
long n, q, i, j, k, l, arr[100000][300000];
cin >> n>>q;
for(i=0; i<n; i++)
{
cin >> k;
for(j=0; j<k; j++)
cin >> arr[i][j];
}
for(l=0; l<q; l++)
{
cin >> i>>j;
cout << arr[i][j]<<endl;
}
return 0;
}
I am trying to solve Variable Sized Arrays problem.
here is the link of the problem
What should be memory order for sequential load-store atomics when certain errors are acceptable
Assume that a user is twisting a knob on a MIDI controller, and the values are being sent to my program as increments and decrements to a stored value. Twisting the knob one way will send a series of decrements, their value depending upon the speed of rotation; twisting the other way increments. I want to keep the stored value (and the value emitted by the following function) to between 0 and 100. If one or a few of the messages get dropped, that's no big deal, but I don't want unexpected major changes in the value emitted by the OffsetResult_
function.
My question then is--do the following memory order directives look correct? The clearest one for me is the compare_exchange_strong
. The program is using that as a store
that can fail, so it seems that release memory ordering applies.
Can I even go to std::memory_order_relaxed
since the major concern is just the atomaticity of the changes to currentV, rather than remembering each change to currentV?
Is there a general way to look at combined load/store functions to see whether it should be acquire, release, or sequentially consistent?
class ChannelModel {
ChannelModel():currentV{0}{};
int OffsetResult_(int diff) noexcept;
private:
atomic<int> currentV;
};
int ChannelModel::OffsetResult_(int diff) noexcept {
int currentV = storedV.fetch_add(diff, std::memory_order_acquire) + diff;
if (currentV < 0) {//fix storedV unless another thread has already altered it
storedV.compare_exchange_strong(currentV, 0, std::memory_order_release, std::memory_order_relaxed);
return 0;
}
if (currentV > 100) {//fix storedV unless another thread has already altered it
storedV.compare_exchange_strong(cv, 100, std::memory_order_release, std::memory_order_relaxed);
return 100;
}
return cv;
}
Note that the actual code is much more complex, and it is reasonable to believe that the response to each message from the controller will take long enough that this function will, on occasion, be called by two threads at nearly the same time.
Assigning to 'int *' from incompatible type 'value_type' (aka 'std::__1::vector
Does anyone know how to call the vector pointer so that it can be assigned to an integer? Following is the code:
void floodFillwithColor(vector<vector<int>>* M, int x, int y, int newC){
int* prevC = M[x][y];
int* newCPtr = &newC;
floodFillUtil(M, x, y, prevC, newCPtr);
};
c++ Visual Studio freaks out when exception thrown
Trying to catch an exception in Visual Studio and realized it was not unwinding the call stack. Narrowed it down to this example and yet it still throws the exception but get's caught by something other than me. Any ideas what I'm missing here?
#include <stdexcept>
#include <iostream>
int main(){
try { throw std::exception("test"); }
catch (...) { std::cout << "something happened"; }
}
visual studio is kind enough to alert me that an exception has been thrown.
After looking over the example and placing breakpoints, I've discovered that VS seems adamant that my catch block is unreachable code. This leaves me further confused and still no answer in sight.
can helgrind (valgrind) be used with c++11 futures
I'm getting what I think are false positives when using helgrind with C++11 futures and packaged tasks. The following is with gcc-6.3.0 and valgrind-3.12 on a CentOS6 system. I've tried to follow the advice in the documentation to provide annotations. Have I done something wrong? What should I do to avoid the false positives, or is there really a race?
drdws0134$ cat hthread.cpp
#include <valgrind/helgrind.h>
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(addr) ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(addr) ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_EXTERN_TEMPLATE -1
#include "thread.cc"
drdws0134$ cat bleep.cpp
#include <valgrind/helgrind.h>
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(addr) ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(addr) ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_EXTERN_TEMPLATE -1
#include <future>
#include <iostream>
std::packaged_task<int()> pt;
void call_pt(){
pt();
}
int main(int, char **){
pt = std::packaged_task<int()>([](){ return 91; });
auto fut = pt.get_future();
std::thread t(call_pt);
std::cout << fut.get() << "\n";
t.join();
return 0;
}
drdws0134$ ./x make bleep
g++ -I/proj/desres/root/CentOS6/x86_64/valgrind/3.12.0-01/include -std=c++14 -pthread -ggdb -O0 -c -o hthread.o hthread.cpp
g++ -I/proj/desres/root/CentOS6/x86_64/valgrind/3.12.0-01/include -std=c++14 -pthread -ggdb -O0 -pthread bleep.cpp hthread.o -o bleep
drdws0134$ ./bleep
91
drdws0134$ which valgrind
valgrind is /proj/desres/root/CentOS6/x86_64/valgrind/3.12.0-01/bin/valgrind
valgrind is /usr/bin/valgrind
drdws0134$ valgrind --tool=helgrind ./bleep
==11476== Helgrind, a thread error detector
==11476== Copyright (C) 2007-2015, and GNU GPL'd, by OpenWorks LLP et al.
==11476== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==11476== Command: ./bleep
==11476==
==11476== ---Thread-Announcement------------------------------------------
==11476==
==11476== Thread #1 is the program's root thread
==11476==
==11476== ---Thread-Announcement------------------------------------------
==11476==
==11476== Thread #2 was created
==11476== at 0x321B8E8A6E: clone (in /lib64/libc-2.12.so)
==11476== by 0x321C00690F: do_clone.clone.0 (in /lib64/libpthread-2.12.so)
==11476== by 0x321C006E6C: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.12.so)
==11476== by 0x4A0C553: pthread_create_WRK (hg_intercepts.c:427)
==11476== by 0x4A0D637: pthread_create@* (hg_intercepts.c:460)
==11476== by 0x407897: __gthread_create(unsigned long*, void* (*)(void*), void*) (gthr-default.h:662)
==11476== by 0x407C0F: std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (thread.cc:163)
==11476== by 0x4056C0: std::thread::thread<void (&)()>(void (&)()) (thread:136)
==11476== by 0x402820: main (bleep.cpp:18)
==11476==
==11476== ----------------------------------------------------------------
==11476==
==11476== Possible data race during read of size 8 at 0x51F0C98 by thread #1
==11476== Locks held: none
==11476== at 0x405AF8: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::get() const (unique_ptr.h:308)
==11476== by 0x404CF3: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::operator*() const (unique_ptr.h:294)
==11476== by 0x404538: std::__future_base::_State_baseV2::wait() (future:329)
==11476== by 0x4064F6: std::__basic_future<int>::_M_get_result() const (future:687)
==11476== by 0x405729: std::future<int>::get() (future:766)
==11476== by 0x40282C: main (bleep.cpp:19)
==11476==
==11476== This conflicts with a previous write of size 8 by thread #2
==11476== Locks held: none
==11476== at 0x406EC6: std::enable_if<std::__and_<std::is_move_constructible<std::__future_base::_Result_base*>, std::is_move_assignable<std::__future_base::_Result_base*> >::value, void>::type std::swap<std::__future_base::_Result_base*>(std::__future_base::_Result_base*&, std::__future_base::_Result_base*&) (move.h:191)
==11476== by 0x406CC2: std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::_M_swap(std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:331)
==11476== by 0x406774: std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::swap(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:1215)
==11476== by 0x405E68: void std::swap<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&, std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:1548)
==11476== by 0x405224: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::swap(std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>&) (unique_ptr.h:355)
==11476== by 0x404A26: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (future:538)
==11476== by 0x406746: void std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (functional:227)
==11476== by 0x405B6B: std::result_of<void (std::__future_base::_State_baseV2::*&&(std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&))(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::type std::__invoke<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (functional:251)
==11476== Address 0x51f0c98 is 24 bytes inside a block of size 64 alloc'd
==11476== at 0x4A07526: operator new(unsigned long) (vg_replace_malloc.c:334)
==11476== by 0x40313F: __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (new_allocator.h:104)
==11476== by 0x402FC4: std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2>&, unsigned long) (alloc_traits.h:416)
==11476== by 0x402DEF: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2> > >(std::__allocated_ptr&) (allocated_ptr.h:103)
==11476== by 0x402C7D: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>*, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr_base.h:613)
==11476== by 0x402BCE: std::__shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr_base.h:1100)
==11476== by 0x402AFF: std::shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()> >::shared_ptr<main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr.h:319)
==11476== by 0x402A5C: std::shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()> > std::allocate_shared<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr.h:620)
==11476== by 0x4029E5: std::shared_ptr<std::__future_base::_Task_state_base<int ()> > std::__create_task_state<int (), main::{lambda()#1}, std::allocator<int> >(main::{lambda()#1}&&, std::allocator<int> const&) (future:1451)
==11476== by 0x402969: std::packaged_task<int ()>::packaged_task<main::{lambda()#1}, std::allocator<int>, void>(std::allocator_arg_t, std::allocator<int> const&, main::{lambda()#1}&&) (future:1503)
==11476== by 0x4028FD: std::packaged_task<int ()>::packaged_task<main::{lambda()#1}, void>(main::{lambda()#1}&&) (future:1493)
==11476== by 0x4027E1: main (bleep.cpp:16)
==11476== Block was alloc'd by thread #1
==11476==
==11476== ----------------------------------------------------------------
==11476==
==11476== Possible data race during read of size 4 at 0x51F0D10 by thread #1
==11476== Locks held: none
==11476== at 0x40573A: std::future<int>::get() (future:766)
==11476== by 0x40282C: main (bleep.cpp:19)
==11476==
==11476== This conflicts with a previous write of size 4 by thread #2
==11476== Locks held: none
==11476== at 0x40761B: std::__future_base::_Result<int>::_M_set(int&&) (future:249)
==11476== by 0x403C70: std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<int>, std::__future_base::_Result_base::_Deleter>, std::_Bind_simple<std::reference_wrapper<main::{lambda()#1}> ()>, int>::operator()() const (future:1325)
==11476== by 0x403ACE: std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<int>, std::__future_base::_Result_base::_Deleter>, std::_Bind_simple<std::reference_wrapper<main::{lambda()#1}> ()>, int> >::_M_invoke(std::_Any_data const&) (functional:1717)
==11476== by 0x405264: std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>::operator()() const (functional:2127)
==11476== by 0x404A08: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (future:533)
==11476== by 0x406746: void std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (functional:227)
==11476== by 0x405B6B: std::result_of<void (std::__future_base::_State_baseV2::*&&(std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&))(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::type std::__invoke<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (functional:251)
==11476== by 0x404D7B: void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}::operator()() const (mutex:602)
==11476== Address 0x51f0d10 is 16 bytes inside a block of size 24 alloc'd
==11476== at 0x4A07526: operator new(unsigned long) (vg_replace_malloc.c:334)
==11476== by 0x4071D6: std::unique_ptr<std::__future_base::_Result<int>, std::__future_base::_Result_base::_Deleter> std::__future_base::_S_allocate_result<int, int>(std::allocator<int> const&) (future:294)
==11476== by 0x40713D: std::__future_base::_Task_state_base<int ()>::_Task_state_base<std::allocator<int> >(std::allocator<int> const&) (future:1373)
==11476== by 0x403280: std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>::_Task_state<{lambda()#1}>({lambda()#1}&&, main::{lambda()#1} const&) (future:1399)
==11476== by 0x4031F1: void __gnu_cxx::new_allocator<int>::construct<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, {lambda()#1}, main::{lambda()#1} const&>(std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>*, {lambda()#1}&&, main::{lambda()#1} const&) (new_allocator.h:120)
==11476== by 0x4030F7: void std::allocator_traits<std::allocator<int> >::construct<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, {lambda()#1}, std::allocator<int> const&>(std::allocator<int>&, std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>*, {lambda()#1}&&, std::allocator<int> const&) (alloc_traits.h:455)
==11476== by 0x402F31: std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<{lambda()#1}, main::{lambda()#1} const&>(main::{lambda()#1}, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr_base.h:520)
==11476== by 0x402CF7: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>*, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr_base.h:615)
==11476== by 0x402BCE: std::__shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr_base.h:1100)
==11476== by 0x402AFF: std::shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()> >::shared_ptr<main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(std::_Sp_make_shared_tag, main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr.h:319)
==11476== by 0x402A5C: std::shared_ptr<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()> > std::allocate_shared<std::__future_base::_Task_state<main::{lambda()#1}, std::allocator<int>, int ()>, main::{lambda()#1}, {lambda()#1}, main::{lambda()#1} const&>(main::{lambda()#1} const&, {lambda()#1}&&, main::{lambda()#1} const&) (shared_ptr.h:620)
==11476== by 0x4029E5: std::shared_ptr<std::__future_base::_Task_state_base<int ()> > std::__create_task_state<int (), main::{lambda()#1}, std::allocator<int> >(main::{lambda()#1}&&, std::allocator<int> const&) (future:1451)
==11476== Block was alloc'd by thread #1
==11476==
91
==11476==
==11476== For counts of detected and suppressed errors, rerun with: -v
==11476== Use --history-level=approx or =none to gain increased speed, at
==11476== the cost of reduced accuracy of conflicting-access information
==11476== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
drdws0134$