I face a strange error with pthreads in C++, I try to run this code:
typedef struct
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
}param;
pthread_t clientThread;
param sentParam ;
sentParam.clienAddr = clientAddress;
sentParam.clientLength= client_info;
sentParam.message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam );
cout <<"i: "<<i<<endl;
the function which be called
void* handleClientRequestRead(void* params)
{
// cout<<"params: "<< ;
string msg = (( param *)(params))->message;
}
When I try to print msg it's empty. Any help will be appreciated
My guess is that when handleClientRequestRead gets called sentParam has already gone out of scope and its memory has been reused for other purposes.
You should allocate memory for your parameters in a location that will still be valid when you'll access it from the thread (e.g. on the heap, keeping in mind that you must free it when you don't need it anymore; a valid help can be shared_ptr).
By the way, in C++ you don't need the typedef trick for structs.
I agree with #Matteo above:
struct param
{
struct sockaddr_in clienAddr;
int clientLength;
string message;
};
void someFunction()
{
static int sentCount = 0;
static param sentParam[10];
// ^^^^^^ Notice these are static
// Thus they will last the length of the program.
// An alternative is to dynamically creation but then you have
// to destroy them at some point.
//
if (count >= 10)
{ throw std::runtime_error("Too many threads");
}
// If you want to keep more than 10 or use a dynamic number
// then use a std::list, NOT a std::vector
sentParam[sentCount].clienAddr = clientAddress;
sentParam[sentCount].clientLength= client_info;
sentParam[sentCount].message=buffString;
cout <<"sentParam: "<<sentParam.message<<endl;
// it prints well.
pthread_t clientThread;
int i = pthread_create(&clientThread, NULL, handleClientRequestRead,&sentParam[sentCount] );
cout <<"i: "<<i<<endl;
if (i == 0)
{
++sentCount;
}
}
Related
I have a strange issue. I allocate char[] values in struct array, but they get lost:
------- The struct is this one :
typedef struct _Settings
{
const char* str;
uint val;
}Settings;
------- I create it like this :
int nn=10;
settings = new Settings[nn];
for (int i = 0; i < nn; i++) {
string strr = "thisOneIs";
strr.append(std::to_string(i));
settings[i].str = strr.c_str();
string teststr = settings[i].str; //// (1)
settings[i].val = i + 1;
}
..... at (1), I get the correct values.
But if I then call this (same place, right after the code above), the settings[i].str is empty:
for (int i = 0; i < nn; i++) {
string teststr = settings[i].str; ///// (2)
std::cout << settings[i].str << "=" << settings[i].val << "\n";
}
... at (2), I get empty.
Does anyone have a clue why? Thanks!
The line at (1) is a problem because you are storing a pointer to some memory that is not valid when the loop ends.
string strr = "thisOneIs"; // A temporary object in the loop.
strr.append(std::to_string(i));
settings[i].str = strr.c_str(); // Pointer that won't be valid when the loop ends.
If you learning about low level language features, it's ok to experiment with using char* and raw memory. If you are trying to get a working program, just use std::string.
Also simplify the definition of Settings. You don't need all the typedef non-sense in C++.
struct Settings
{
std::string str;
uint val;
};
The memory leak caused by the line indicated. "pendingSendReqs.push_back(&f);" in the sendreq() method. I am new to c++ so I can't seem to figure out why the memory leak is occuring. The size of memory leaked is 16 bytes.
class Station {
struct Frame {
enum { Token, Data, Ack } type; // type of frame
unsigned int src; // source id
unsigned int dst; // destination id
unsigned int prio; // priority
} frame;
unsigned int stnId;
static unsigned int requests; // total send requests (if needed)
void data( Frame frame ); // pass frame
void main(); // coroutine main
Station *nextStation;
vector<Frame*> pendingSendReqs;
public:
Station( unsigned int id ) : stnId(id) { }
~Station() {
for (int i = 0; i < pendingSendReqs.size(); i++) {
delete pendingSendReqs.at(i);
cout << "~: " << pendingSendReqs.at(i) << endl;
}
}
//unsigned int getId() { return stnId; }
void setup( Station *nexthop ) { // supply next hop
//*nexthop is the object
nextStation = nexthop;
//cout << "size: " << sizeof(*nexthop) << endl;
}
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) { // store send request
Frame f;
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
}
void start(); // inject token and start
};
This is not a memory leak
pendingSendReqs.push_back(&f);
it is future undefined behaviour. You are storing the address of a local variable. Any attempt to de-reference one of those pointers outside of the scope of the function is undefined behaviour.
You have to ask yourself whether you really need a vector of pointers. If you don't know the answer to that, it is likely that you don't.
You're storing pointers to local variables, which will automatically get destroyed, inside the vector. This is illegal.
vector<Frame*> pendingSendReqs;
// this is a vector of pointers to struct and not a vector of structs
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) {
Frame f; // this automatic variable will get destroyed when sendreq returns
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
// because you're going to hold on to this address which will mean
// nothing when this function returns
}
The way you intend to do it is:
vector<Frame> pendingSendReqs;
and inside sendreq:
pendingSendReqs.push_back(f); // store the object's copy instead of it's address so that it outlives the life of this local
when
void sendreq( unsigned int round, unsigned int dst, unsigned int prio )
ends,
your vector pendingSendReqs will contain pointers to variables that have been eliminated ( because are local variable ), and will contain garbage, and will give you a crash.
I define arrays of integers in my code:
unsigned int tara[1024][3];
unsigned int data[1024][4];
I have storage structure, that allows me to pass them as void*:
struct storage {
unsigned int (*data)[4];
unsigned int (*tara)[3];
};
This is my use of structure above:
int main() {
unsigned int tara[1024][3];
unsigned int data[1024][4];
storage but_data;
but_data.data = data;
but_data.tara = tara;
tara_button.setCallback(taraButtonCallback, (void*)&but_data); //Some UI class
while(true); //The program
return 0;
}
In callback, this is how I try to access data:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data_struct = (storage*)but_data;
int max = -5;
int max_value = 0;
cout<<data_struct->data[0][0]<<'\n'; //!!ERROR!!
return true;
}
This is runtime error I get:
Unhandled exception at 0x00394f1c in OpenCV.exe: 0xC0000005: Access violation reading location 0x00000005.
Edit:
The problem is not related to to where is the but_data defined! This callback works:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data = (storage*)but_data;
set_tara(data->data, data->tara, *data->mat);
*(data->tara_set) = true;
return true;
}
void set_tara(unsigned int data[][4], unsigned int tara[][3], Mat &UI_bot)
{
UI_bot = Scalar(0, 0, 0);
for(int x=0; x<cam_frame_width; x++) {
tara[x][0]=data[x][0];
tara[x][1]=data[x][1];
tara[x][2]=data[x][2];
}
}
At the time the callback is called, but_data is already destroyed:
storage but_data;
It is allocated locally, which means that its lifetime is limited with the end of current function. After the function is completed, it ceases to exist, and the callback uses a dangling pointer.
Just assign it to a variable and print it
int taraButtonCallback(void* but_data)
{
struct storage* data = ( struct storage*)but_data;
int max = -5;
int max_value = 0;
int val = data->data[0][0];
cout <<val ; //!!works!!
return 0;
}
I think cout is unable to handle [][] in this case .. I am not sure why someone can enlighten both of us
You could try allocating the variable storage but_data like this:
storage *but_data = new storage;
effectively creating a variable with infinite lifetime.
Than you would define your callback function a bit differently (because you already have a pointer, so you do not need the address of the variable) - like this:
tara_button.setCallback(taraButtonCallback, (void*)but_data);
//note the lack of '&' sign before the but_data variable name
Just don't forget to delete it after you no longer need it!
delete but_data;
I'm Java user coming over to C++, and I am having a hard time understanding what is going wrong with this statement. My program has been segfaulting anywhere I put the push_back command. So I'm wondering what exactly is going on.
class Process {
public:
int nice;
int arrivalTime;
int cpuBursts;
list<int> burstList;
Process() {
burstList.push_back(10); // Segfaults here...
}
};
Here is the full code:
#include<iostream>
#include<stdlib.h>
#include<fstream>
#include<list>
#include<string.h>
using namespace std;
int calcTimeslice(int priority);
int calcOriginalPrio(int nice);
int readFile(int ,char **);
int calcPrioBonus(int,int);
void tokenizeAndAdd(char *);
class Bursts {
public:
int isCPUBurst;
int time;
Bursts() {}
// Constructor to make it easier to add to list
Bursts(int tempIsCPU, int tempTime) {
isCPUBurst = tempIsCPU;
time = tempTime;
}
};
class Process {
public:
int nice;
int arrivalTime;
int cpuBursts;
list<int> burstList;
Process() {
burstList.push_back(10);
}
};
int main(int arg, char **argv) {
// This is if the file was not correctly read into the program
// or it doesnt exist ...
if(readFile(arg,argv)==-1) {
cout << "File could not be read. \n";
return -1;
}
//cout << "Original Calc Whatever: " << calcOriginal(19) << '\n';
return 0;
}
/*
* Calculates the timeslice based on the priority
*/
int calcTimeslice(int priority) {
double finalCalc;
// This is the given function in the prompt
finalCalc = ( (1 - (priority / 140)) * 290 + (.5) ) + 10;
// Cast to int, this will be a truncate
return ((int)finalCalc);
}
int readFile(int arg, char **argv) {
char *temp,*pointer;
int endOfFile = 1;
// While its not the end of the file
while(endOfFile) {
// Read in the input from stdin
fgets(temp,256,stdin);
// Check to see if this line had a * in it
if(*temp =='*')
endOfFile = 0;
else
tokenizeAndAdd(temp);
}
return 0;
}
void tokenizeAndAdd(char *string) {
char *token = strtok(string," \n");
int i = 0;
Process p;
while(token != NULL) {
cout << token << endl;
if(i>2) { // If it is odd (CPU burst)
if(i%2 == 1) {
int tempInt = atoi(token);
//p.burstList.push_back(tempInt);
}
else { // If it is even (IO burst)
int tempInt = atoi(token);
//p.burstLis.push_back(tempInt);
}
}
else if(i==0)
p.nice = atoi(token);
else if(i==1)
p.arrivalTime = atoi(token);
else if(i==2)
p.cpuBursts = atoi(token);
token = strtok(NULL," \n");
i++;
}
//cout << p.nice << " " << p.arrivalTime << " " << p.cpuBursts << "\n";
//i = 0;
//cout << p.burstList.size() << "\n";
// cout <<
//}
return;
}
/*
* Calculates and returns the original priority based on the nice number
* provided in the file.
*/
int calcOriginalPrio(int nice) {
double finalCalc;
// This is the given function from the prompt
finalCalc = (( nice + 20 ) / 39 ) * 30 + 105.5;
// Cast to int, this is a truncate in C++
return ((int)finalCalc);
}
/*
* Calculates the bonus time given to a process
*/
int calcPrioBonus(int totalCPU, int totalIO) {
double finalCalc;
// How to calculate bonus off of the prompt
if(totalCPU < totalIO)
finalCalc = ( (1 - (totalCPU / (double)totalIO)) * (-5)) - .5;
else
finalCalc = ( (1 - (totalIO / (double)totalCPU)) * 5) + .5;
// Cast to int
return ((int)finalCalc);
}
You are using temp uninitialized in the following code:
char *temp;
...
while(endOfFile) {
fgets(temp,256,stdin);
...
This can have any side effect, since it most likely destroys your stack or parts of the heap memory. It could fail immediately (when calling the fgets() function), it could fail later (as in your sample) or it could even run fine - maybe until you upgrade your OS, your compiler or anything else, or until you want to run the same executable on another machine. This is called undefined behaviour.
You need to allocate space for the temp variable, not a pointer only. Use something like
char temp[256];
...
while(endOfFile) {
fgets(temp,256,stdin);
...
For more information, see the fgets() documentation. The first parameter is a pointer to a char array - that is where fgets() will store the bytes which have been read. In your code, you pass an uninitialized pointer which means that fgets() will store the bytes to an undefined memory location - this is catched by the OS which terminates your application with a segmentation fault.
BTW: You should consider enabling pedantic warnings when compiling - I compiled with
g++ -Wall -pedantic -o list list.cpp
which gave me the following warning:
list.cpp: In function 'int readFile(int, char**)':
list.cpp:76:26: warning: 'temp' may be used uninitialized in this function [-Wuninitialized]
This is probably not the actual code with the error you report. But here is one of the problems with give you UB.
char *temp,*pointer; // uninicialized pointer char temp[1000]; could work?
int endOfFile = 1;
// While its not the end of the file
while(endOfFile) {
// Read in the input from stdin
fgets(temp,256,stdin);
The last function call will read a maximum of 256 bytes from stdin and will write it in the memory pointed by pointer tmp. So, you need to first "prepare" that memory. But with char *tmp; you only define a pointer, with no defined value, that is, with point to some possible unexisting or illegal/inaccessible for you memory. In contrary, char tmp[1000]; will define in the "stack memory" a block of 1000 bytes, with you can point to using simple the variable tmp. Hope this is clear for you.
EDIT:
I don't know why that would change the behavior of the list,
You are right. That is Undefined Behavior (UB). When you write in some unknown memory (pointed by an uninitialized pointer) you may overwrite data or even code that will broke somewhere the correct function of your program in an unpredicted way.
You will need to learn more about pointers but better you use std::string, and look how parse your file using string and stringstream. That will manage for you the memmory,
I am sure this is a very simple fix and I feel dumb asking it but here it goes.
I need help with a struct and passing info from a gather function to a save or set function, and then passing it again to another function for further use.
Basically, it looks like this to start. I'll just add short snips of the code. All can be provided if you would like to see it.
I right now am just looking for the proper way to pass struct defined data from get.... to set.... functions.
struct printype
{
char dots[8][15];
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
};
int getunknown15(); // prototypes
int setunknown15(int);
then we have a simple main.
int main()
{
printype pt;
pt.unknown15=getunknown15();
pt.unknown15=setunknown15(12);
pt.serial11_14=getserial11_14();
pt.serial11_14=setserial11_14("12345678");
pt.year8=getyear8();
pt.year8=setyear8(44);
pt.month7=getmonth7();
pt.month7=setmonth7(11);
pt.day6=getday6();
pt.day6=setday6(12);
pt.hour5=gethour5();
pt.hour5=sethour5(12);
pt.minute2=getminute2();
pt.minute2=setminute2(23);
cout <<"-----------------------------------------------------"<<endl;
cout <<" Let's Get Started"<<endl;
cout <<"-----------------------------------------------------"<<endl;
setup(pt.dots); // sets up the array
dpinfo(pt); // prints out the final array
ftarray(pt);
spar(pt.dots);
darray(pt.dots);
}
and finally the get and set array functions.
int getunknown15()
{
printype tem;
cout <<"-----------------------------------------------------"<<endl;
cout <<" Enter the Unkown Variable (0-127): ";
cin >>tem.unknown15;
cout <<"-----------------------------------------------------"<<endl;
return tem.unknown15;
}
next is
int setunknown15(int tem)
{
printype pp;
if (tem>127||tem<0)
{
cout << "Error" << endl;
return 0;
}
else
{
pp.unknown15 = tem;
return pp.unknown15;
}
}
I hope this isn't too much to read and understand
Anyway, I know this has a really simple answer but my brain just isn't working right now.
Edit: As StilesCrisis stated, Send struct as parameter is quiet stupid in this case. better use a const reference.
Well, I am not sure if I understand your question correctly. You can simply send struct to another function as parameter, or as a pointer.
like:
void SetStruct(const printype& var);
printype GetStruct();
Is it what you are looking for?
Please use the following access to the your fields, (by reference):
struct printype *myPtr = new printype;
myPtr->day6 = 43;
When use pointer instead of a normal variable, you should use -> instead . to access your fields.
I know this is kind of old but I thought I should give it a shot, since you are using C++ and it looks like you are trying to use some OO practices (I think), you don't need to start with a struct, even though OO principles can be applied using them as well though not as elegantly.
you can define your class header file as such.
#ifndef PRINTYPE_H
#define PRINTYPE_H
#include <string>
using namespace std;
class printype
{
private: // we always want to declare our member fields private for safety/managements reasons, no one will be able to access them outside.
char dots[8][15];
int unknown15; // can have values of 0..127
string serial11_14; // 8 characters 00000000...99999999
int year8; // without century, 0..99
int month7; // 1..12
int day6; // 1..31
int hour5; // 0..23
int minute2; // 0..59
void init(); // This is the method we use to initialize our starting state.
public: // This is our public methods, how people deal with/get/set our state.
printype(); // This is our default constructor
printype(const printype& print_type); // This our copy constructor
virtual ~printype(); // This is our destructor, its virtual, making safer for inheritance.
// This is our setters/getters
void setUnknown(int unknown);
int getUnknown();
void setYear(int year);
int getYear();
void setMonth(int mont);
int getMonth();
// and well you get the idea, you can add more methods.
};
#endif
and the accompanying class source file with your functions implementation
printype::printype()
{
this->init(); // Initialize all your vatiables, safer to just define a function to this.
}
printype::printype(const printype& orig) // copy constructor
{
this->setUknown(orig.getUnknown());
this->setDay(orig.getDay());
this->setDots(orig.getDots());
// you get the idea ...
}
printype::~printype()
{
// Have anything you need to do before destroying the object.
}
void printype::init()
{
this->setUnknwon(0);
this->setyear(0);
this->setMonth(1);
char dots[8][15] = {'\0'};
this->setDots(dots);
// you get the idea, you want to initialize all your variables since, for the most part they initially hold garbage.
}
void printype::setUnknown(int unknown)
{
if (unknown >= 0 && unknown < 127)
this->unknown15 = unknown;
else
error("Expecting unknown to be between 0 and 127"); // error should probably print the error and/or exit(-1) up to u
}
int printype::setYear(int year)
{
if (year >= 1 && year <= 99)
this->year8 = year;
else
error("Expecting year between 0 and 99"); // you may want to implement an error function!
}
int printype::getYear()
{
return this->year8;
}
void printype::setDots(char dots[8][15])
{
// you may want to do some verifications
memcpy(this->dots, dots, sizeof(dots));
}
void printype::setDots(char **dots) // this is a bit unsafe, use at your own risk.
{
if (dots)
{
unsigned int index = 0;
for (index = 0; index < 8; index++)
if (dots[index])
memcpy(this->dots[index], dots[index], 15);
else
error("dots required pointer ...");
}
else
error("dots required pointer ...");
}
char **getDots() // We will be returning a copy, we don't want the internal state to be affected, from outside, by using reference or pointers.
{
char **dots = new char*[8];
unsigned int index = 0;
for (index = 0; index < 8; index++)
{
dots[index] = new char[15];
memcpy(dots[index], this->dots[index], 15);
}
return dots;
}
// and well you get the idea ...
to use your class
printype *print_type_p = new print_type();
// or
printype pront_type_p();
// use the different public method to update the internal state.
print_type_p->setYear(3);
// or
print_type.setYear(3);
print_type_p->getYear();
// and so on.