Thread Argument Problem - c++

I have working on multithreaded application I am passing IMAGETHREADINFO structure in thread here nSock is showing garbage value. What is the problem here.pointer to IMAGETHREADINFO is declared as member variable of CServerConnectionMgr class.
typedef struct
{
int nScok;
CServerConnectionMgr* pConMgr;
}IMAGETHREADINFO;
void StartImageThread(SOCKET nSock)
{
stThreadInfo = new IMAGETHREADINFO;
stThreadInfo.pConMgr = this;
stThreadInfo.nScok = nSock;
m_hRecordImageThread = CreateThread ( NULL,0, (LPTHREAD_START_ROUTINE)StreamImageThread,(void*)&stThreadInfo, 0,&m_nRecordImageThreadID);
if ( NULL == m_hRecordImageThread)
{
return;
}
int CServerConnectionMgr::StreamImageThread(void *args)
{
IMAGETHREADINFO *pImageThreadInfo = (IMAGETHREADINFO*)&args;
}
This is variable pImageThreadInfo->nSock showing some garbage value
This pImageThreadInfo->pConMgr is coming correctly
I this is showing wrong value

(void*)&stThreadInfo is a pointer to the stThreadInfo pointer. You likely want to remove the &
And then, also change IMAGETHREADINFO *pImageThreadInfo = (IMAGETHREADINFO*)&args;, remove the &

Related

a value of type "void *" cannot be assigned to an entity of type "RANDOMSTRUCT *"

So I was working on malloc in void. And I have a code:
int iInitRandomPhaseArrays(WS_ELEMENT *Aufbau, RANDOMSTRUCT **random)
{
WS_ELEMENT *Act;
int iCounter = 0, i;
RANDOMSTRUCT *dummy;
Act = Aufbau;
if (*random != NULL)
return -1;
while (Act != NULL)
{
if (Act->operation == Linsenarray)
iCounter++;
Act = Act->pNext;
}
if (iCounter)
{
dummy = malloc(iCounter * sizeof(random));
ran1_3ARG(&ran1_idum, &ran1_iy, ran1_iv);
dummy[0].idum = ran1_idum;
dummy[0].iy = ran1_iy;
memcpy(dummy[0].iv, ran1_iv, sizeof(ran1_iv));
for (i = 0; i < iCounter; i++)
ran1_3ARG(&dummy[i].idum, &dummy[i].iy, dummy[i].iv);
dummy[0].Anzahl = iCounter;
*random = dummy;
}
return iCounter;
}
here error:
a value of type "void *" cannot be assigned to an entity of type "RANDOMSTRUCT *"
Can anyone help me solve it?
Change the line:
dummy = malloc(iCounter * sizeof(random));
to say:
dummy = (RANDOMSTRUCT *)malloc(iCounter * sizeof(RANDOMSTRUCT));
dummy = malloc(iCounter * sizeof(random));
this allocates the wrong amount of memory (a multiple of a pointer size, not the pointed-to) and returns a void*. In c++ void* doesn't implicitly convert to other pointer types. In c it does.
Assuming you actually mean to use C-isms in C++ code, write this:
template<class T>
T* typed_malloc( std::size_t count = 1 ) {
return static_cast<T*>(malloc( sizeof(T)*count ));
}
this function is a type-safe version of malloc that handles 9999/10000 uses, and prevents an annoying class of bugs.
Then change the line of code to:
dummy = typed_malloc<RANDOMSTRUCT>(iCounter);
Sometimes using malloc in c++ isn't easy to remove, because your code interacts with c code. This kind of change can eliminate bugs before they happen as you modify c code to c++ relatively transparently.

C++ Create std::list in function and return through arguments

How to correct return created std::list through function argument? Now, I try so:
bool DatabaseHandler::tags(std::list<Tag> *tags)
{
QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
QSqlQueryModel model;
model.setQuery(sql);
if(model.lastError().type() != QSqlError::NoError) {
log(sql);
tags = NULL;
return false;
}
const int count = model.rowCount();
if(count > 0)
tags = new std::list<Tag>(count);
else
tags = new std::list<Tag>();
//some code
return true;
}
After I can use it:
std::list<Tag> tags;
mDB->tags(&tags);
Now, I fix my function:
bool DatabaseHandler::tags(std::list<Tag> **tags)
{
QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
QSqlQueryModel model;
model.setQuery(sql);
if(model.lastError().type() != QSqlError::NoError) {
log(sql);
*tags = NULL;
return false;
}
const int count = model.rowCount();
if(count > 0)
*tags = new std::list<Tag>(count);
else
*tags = new std::list<Tag>();
for(int i = 0; i < count; ++i) {
auto record = model.record(i);
Tag tag(record.value(Table::KEY_ID).toInt());
(*tags)->push_back(tag);
}
return true;
}
It works but list return size 4 although loop executes only 2 iterations and empty child objects (if I just called their default constructor). The Tag class hasn't copy constructor.
Since you passed an already instantiated list as a pointer to the function, there is no need to create another list.
In that sense, you question is pretty unclear. I'd suggest you read up a bit on pointers, references and function calls in general.
http://www.cplusplus.com/doc/tutorial/pointers/
http://www.cplusplus.com/doc/tutorial/functions/
UPDATE: I still strongly suggest you read up on the mentioned topics, since you don't know these fundamental points.
Anyway, this is what you probably want to do (event though I would suggest using references, here is the solution with pointers):
bool someFunc(std::list<Tag> **tags) {
// by default null the output argument
*tags = nullptr;
if (error) {
return false;
}
// dereference tags and assign it the address to a new instance of list<Tag>
*tags = new std::list<Tag>();
return true
}
std::list<Tag> *yourList;
if (someFunc(&yourList)) {
// then yourList is valid
} else {
// then you had an error and yourList == nullptr
}
However, this is not idiomatic C++. Please read a modern book or tutorial.
Use a reference.
bool DatabaseHandler::tags(std::list<Tag>& tags);
std::list<Tag> tags;
mDB->tags(tags);
You'll have to change all the -> to ., of course. Every operation done on the reference in the function will be done to the original tags list it was called with.
EDIT: If you want to create the list inside the function and return it, you have a couple options. The closest, I think, is to just return a list pointer, and return nullptr if the function fails.
//beware, pseudocode ahead
std::list<Tag>* DatabaseHandler::tags() //return new list
{
if (success)
return new std::list<Tag>(...); //construct with whatever
else
return nullptr; //null pointer return, didn't work
}
std::list<Tag> tags* = mDB->tags();
You could alternatively have it return an empty list instead, depending on how you want it to work. Taking a reference to a pointer would work the same way, too.
bool DatabaseHandler::tags(std::list<Tag>*&); //return true/false
std::list<Tag>* tags;
mDB->tags(tags); //tags will be set to point to a list if it worked

an static function used in StringHashTable thread-safe?

I have got an StringHashTable class from
http://preshing.com/20110603/hash-table-performance-tests/
The following are parts of source :
class StringHashTable
{
static uint fnv1Hash(const char *key)
{
unsigned int hash = 2166136261ul;
for (const char *s = key; *s; s++)
hash = (16777619 * hash) ^ (*s);
return hash;
};
uint &operator[](const char *key)
{
uint hash = fnv1Hash(key) & (m_tableSize - 1);
Bucket *firstBucket = m_table + hash;
Bucket *b = firstBucket;
if (b->key)
{
do
{
if (strcmp(b->key, key) == 0)
return b->value;// Found existing bucket
b = b->next;
} while (b);
}
..........
}
}
Suppose that I have the global var :
StringHashTable hashtable(1024) ; //m_tableSize now 1024
And then the following is in main :
hashtable["0000"] = 0 ;
....
hashtable["9999"] = 9999 ;
After fill in all the data I need , thread 1 to n will get value according to key
while(1)
{
s = get(); //return string like "0000" ... "9999"
echo << hashtable[s.c_str()] << endl ;
}
I wonder if the StringHashTable would work fine in thread at first ,
because the function fnv1Hash is static , on second thought , there is no
static member data in this StringHashTable , so while thread1 is doing
hashtable["0000"] and thread2 is doing hashtable["9999"] at the very same time
both thread1 are calling fnv1Hash they will both get the right hash returned !!!
My question is : different thread call static uint fnv1Hash(const char *key) with
different key at the very same time still work fine ? In StringHashTable , fnv1Hash
is static for any reason ?!
The function fnv1Hash() doesn't access any non-local state other than the data pointed to by key. Assuming the content of the array key points to isn't written to concurrently, there is no threading issue. Of course, if another thread writes to the array pointed to by key, all bets are off.
Given that fnv1Hash() does access any of the object's data it doesn't need a this pointer. Thus, it is made static to indicate both to the human reader and the compiler that the objects won't be accessed implicitly. For the compiler the upshot is that it doesn't need to pass a this pointer.

Member variables of a object get overridden when creating another object in the object

I have a memory issue with a class of mine. The issue occurs when I create an object in a member function of a class. It is about the class below. I removed the member functions because they aren’t necessary:
class User
{
private:
bool locked;
bool active;
std::vector<City> * userCitys;
UserData userData;
Credentials credentials;
The problem occurs when I call this function:
int User::addCity(CityData cityData)
{
lockUserObject(); //Everything is fine here
City cityToAdd; //When this object is created, the memory of userCitys will get overridden
cityToAdd.activate();
userCitys->push_back(cityToAdd);
int cityID = userCitys->size() - 1;
userCitys->at(cityID).editCityData(cityData);
unlockUserObject();
return cityID;
}
In the first place I created userCitys on the stack. For test purpose I placed it on the Heap. The address of userCitys get overridden by some data. I can’t find the problem. the City is just a basic class:
Part of the header:
class City
{
private:
bool active;
Supplies supplies;
std::vector<Building> buildings;
std::vector<Company> companies;
std::vector<Share> shares;
std::vector<Troop> troops;
CityData cityData;
Constructor:
City::City()
{
active = false;
}
How is it possible that userCitys get overridden? This all happens on a single Thread so that can’t be a problem. I tried a lot of thing, but I can’t get it to work. What is the best approach to find the problem?
Edit:
Lock function:
void User::lockUserObject()
{
for( int i = 0; locked ; i++)
{
crossSleep(Settings::userLockSleepInterval);
if( i >= Settings::userLockMaxTimes )
Error::addError("User lock is over userLockMaxTimes",2);
}
locked = true;
}
I call the code here (Test function):
City * addCity(User * user)
{
Location location;
location.x = 0;
location.y = 1;
CityData citydata;
citydata.location = location;
citydata.villagers = 0;
citydata.cityName = "test city";
int cityID = user->addCity(citydata); //addCity is called here
City * city = user->cityAction(cityID);;
if( city == NULL)
Error::addError("Could not create a city",2);
return city;
}
The add user (Test code):
User * addUser()
{
UserData test;
test.name = "testtest";
Credentials testc("testtest",3);
//Create object user
int userID = UserControle::addUser(test,testc);
User * user = UserControle::UserAction(userID);
if( user == NULL)
Error::addError("Could not create a user",2);
return user;
}
My test function:
void testCode()
{
User * user = addUser();
City * city = addCity(user);
}
This function in called in main:
int main()
{
testCode();
return 0;
}
Here are UserAction and addUser in UserControle:
int UserControle::addUser(UserData userdata, Credentials credentials)
{
int insertID = -1;
for( int i = 0; i < (int)UserControle::users.size(); i++)
{
if( !UserControle::users.at(i).isActive() )
{
insertID = i;
break;
}
}
User userToInsert(userdata,credentials);
if( insertID != -1 )
{
UserControle::users.insert( UserControle::users.begin() + insertID,userToInsert);
return insertID;
}
else
{
UserControle::users.push_back(userToInsert);
return UserControle::users.size() - 1;
}
}
User* UserControle::UserAction(int userID) //check all indexes if greater then 0!
{
if( (int)UserControle::users.size() <= userID )
{
Error::addError("UserAction is out of range",3);
return NULL;
}
if( !UserControle::users.at(userID).isActive())
{
Error::addError("UserAction, the user is not active.",3);
return NULL;
}
return &UserControle::users[userID];
}
There's a few things you could try:
Remove code until the fault goes away. In other words, distill a minimal example from your code. I guess you'll then see the error yourself, otherwise post that small example program here and others will.
Don't use raw pointers. The question with those is always who owns what they point to. Use smart pointers instead, e.g. unique_ptr (C++11) or auto_ptr (C++98) for exclusive ownership.
If you have pointer members like "userCities", you need to think about what happens when copying instances of that class (you already wrote a proper destructor, or?). So, either prevent copying (make copy-constructor and assignment operator private and without implementing it) or implement them in a way that the vectors are properly cloned and not shared between different instances.
Don't use C-style casts. If those are necessary to get anything through the compiler, the code is probably broken.

Function has corrupt return value

I have a situation in Visual C++ 2008 that I have not seen before. I have a class with 4 STL objects (list and vector to be precise) and integers.
It has a method:
inline int id() { return m_id; }
The return value from this method is corrupt, and I have no idea why.
debugger screenshot http://img687.imageshack.us/img687/6728/returnvalue.png
I'd like to believe its a stack smash, but as far as I know, I have no buffer over-runs or allocation issues.
Some more observations
Here's something that puts me off. The debugger prints right values in the place mentioned // wrong ID.
m_header = new DnsHeader();
assert(_CrtCheckMemory());
if (m_header->init(bytes, size))
{
eprintf("0The header ID is %d\n", m_header->id()); // wrong ID!!!
inside m_header->init()
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
eprintf("The details are %d,%d,%d,%d\n", m_qdcount, m_ancount, m_nscount, m_arcount);
// copy the flags
// this doesn't work with a bitfield struct :(
// memcpy(&m_flags, bytes + 2, sizeof(m_flags));
//unpack_flags(bytes + 2); //TODO
m_init = true;
}
eprintf("Assigning an id of %d\n", m_id); // Correct ID.
return
m_header->id() is an inline function in the header file
inline int id() { return m_id; }
I don't really know how best to post the code snippets I have , but here's my best shot at it. Please do let me know if they are insufficient:
Class DnsHeader has an object m_header inside DnsPacket.
Main body:
DnsPacket *p ;
p = new DnsPacket(r);
assert (_CrtCheckMemory());
p->add_bytes(buf, r); // add bytes to a vector m_bytes inside DnsPacket
if (p->parse())
{
read_packet(sin, *p);
}
p->parse:
size_t size = m_bytes.size(); // m_bytes is a vector
unsigned char *bytes = new u_char[m_bytes.size()];
copy(m_bytes.begin(), m_bytes.end(), bytes);
m_header = new DnsHeader();
eprintf("m_header allocated at %x\n", m_header);
assert(_CrtCheckMemory());
if (m_header->init(bytes, size)) // just set the ID and a bunch of other ints here.
{
size_t pos = DnsHeader::SIZE; // const int
if (pos != size)
; // XXX perhaps generate a warning about extraneous data?
if (ok)
m_parsed = true;
}
else
{
m_parsed = false;
}
if (!ok) {
m_parsed = false;
}
return m_parsed;
}
read_packet:
DnsHeader& h = p.header();
eprintf("The header ID is %d\n", h.id()); // ID is wrong here
...
DnsHeader constructor:
m_id = -1;
m_qdcount = m_ancount = m_nscount = m_arcount = 0;
memset(&m_flags, 0, sizeof(m_flags)); // m_flags is a struct
m_flags.rd = 1;
p.header():
return *m_header;
m_header->init: (u_char* bytes, int size)
header_fmt *h = (header_fmt *)bytes;
m_id = ntohs(h->id);
eprintf("Assigning an id of %d/%d\n", ntohs(h->id), m_id); // ID is correct here
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
You seem to be using a pointer to an invalid class somehow. The return value shown is the value that VS usually uses to initialize memory with:
2^32 - 842150451 = 0xCDCDCDCD
You probably have not initialized the class that this function is a member of.
Without seeing more of the code in context.. it might be that the m_id is out of the scope you expect it to be in.
Reinstalled VC++. That fixed everything.
Thank you for your time and support everybody! :) Appreciate it!