I want to use the Irrnet network library in an Irrlicht game.
The source code uses Linux sockets and I'm trying to port it for Windows replacing it with code that uses Windows' Winsock2.
The library compiles successfully but when I try to run the Quake example it crashes. I located the line at which the program stops but i can't figure out how to solve the problem.
The program stops at the second call of the function getNextItem
class NetworkType {
public :
NetworkType();
~NetworkType();
template<class T>
void getNextItem(irr::core::vector3d<T>& data);
private:
typedef std::queue<std::string> Container;
Container items;
};
template<class T>
void NetworkType::getNextItem(irr::core::vector3d<T>& data) {
T X, Y, Z;
std::istringstream item(items.front());
// the program does not get here the second time it calls this function
items.pop();
item >> X;
item >> Y;
item >> Z;
data = irr::core::vector3d<T>(X, Y, Z);
}
and exactly at this line
std::istringstream item(items.front());
Can anyone tell me why does the program stop the second time it gets to this line ?
here is the link for the complete source code
I assume by "stops" you mean "crashes" in some fashion? Likely causes for a crash on the line in question are:
The NetworkType instance that is invoking the getNextItem() method is garbage (the this pointer is garbage or null). This could happen due to bad pointer math elsewhere, a premature delete or destruction of the instance, et cetera. This would manifest as a fault when the program attempted to access the items member.
The items container is empty. In these cases the return value of front() is undefined (since it is a reference) and the constructor for istringstream may be crashing. front() itself may be raising a debug/runtime check error as well depending on your compiler and its configuration.
Actually you might have a runtime error on this one if the dequeue is empty: MSDN deque
So just check the deque isn't empty before you try to pop a value from it.
if(items.size()>0)
{
//do things
}
else
{
//error deque empty
}
[edit] confounded std and (I guess) MSDN ( OP doesn't say) lib.
Related
I have began learning C++ for Arduino and have run into some troubles.
I have some functions reading/writing to SPIFFS files.
Since the code for opening configuration files is common I would want to have a separate function to handle it.
I have come up with following function declaration
ConfigFileOpenStatus DeviceOpenConfigFile(const char *path, File *file);
The function accepts pointer to char array for the file path, and pointer to opened file.
I then tried to make following function definition
ConfigFileOpenStatus DeviceOpenConfigFile(const char *path, File *file)
{
if (SPIFFS.exists(path))
{
file = &SPIFFS.open(path, "r+");
return !file ? Failed : Opened;
}
else
{
file = &SPIFFS.open(path, "w+");
return !file ? Failed : Created;
}
}
That did not work as compiler complained with error error: taking address of temporary [-fpermissive]
As I understand this means that the file object will be disposed once DeviceOpenConfigFile function returns?
So my question is whether its possible to implement a function in a way where I can get File object reference and release it later?
SPIFFS.open apparently returns File, by value. The returned value will be a temporary variable available on that line. So taking the address of that one doesn't make any sense, for the same reason as int func (void); ... &func() doesn't make any sense. It has nothing to do with the surrounding DeviceOpenConfigFile function.
It doesn't make sense to assign a new address to pointer passed by parameter, for the same reason as void func (int x) { x = 0; } doesn't make sense - you change a local variable only, nothing on the caller side gets changed and nothing gets returned to the caller.
It would seem that the solution you are looking for is this:
ConfigFileOpenStatus DeviceOpenConfigFile(const char *path, File* file)
{
...
*file = SPIFFS.open(path, "r+");
where file is allocated on the caller-side.
I am writing a function:
void callFunctionAt(uint32_t address){
//There is a void at address, how do I run it?
}
This is in Atmel Studio's C++. If previous questions are to be believed, the simple answer is to write the line "address();". This cannot be correct. Without changing the header of this function, how would one call the function located at the address given?
The answer should be system-agnostic for all micro controllers which support standard c++ compilation.
The common way to do this is to give the argument the correct type. Then you can call it right away:
void callFunctionAt(void (*address)()) {
address();
}
However, since you wrote "Without changing the header of this function [...]", you need to cast the unsigned integer to a function pointer:
void callFunctionAt(uint32_t address) {
void (*f)() = reinterpret_cast<void (*f)()>(address);
f();
}
But this is not safe and not portabel because it assumes that the uint32_t can be casted into a function pointer. And this needs not to be true: "[...] system-agnostic for all micro controllers [...]". Function pointers can have other widths than 32 bits. Pointers in general might consist of more than the pure address, for example include a selector for memory spaces, depending on the system's architecture.
If you got the address from a linker script, you might have declared it like this:
extern const uint32_t ext_func;
And like to use it so:
callFunctionAt(ext_func);
But you can change the declaration into:
extern void ext_func();
And call it directly or indirectly:
ext_func();
callFunctionAt(&ext_func);
The definition in the linker can stay as it is, because the linker knows nothing about types.
There is no generic way. It depends on which compiler you are using. In the following I'll assume avr-g++ because it's common and freely available.
Spoiler: On AVR, it's more complicated than on most other machines.
Suppose you actually have a uint32_t address which would be a byte address. Function pointers in avr-g++ are word addresses actually, where a word has 16 bits. Hence, you'll have to divide the byte address by 2 first to get a word address; then cast it to a function pointer and call it:
#include <stdint.h>
typedef void (*func_t)(void);
void callFunctionAt (uint32_t byte_address)
{
func_t func = (func_t) (byte_address >> 1);
func();
}
If you started with a word address, then you can call it without further ado:
void callFunctionAt (uint32_t address)
{
((func_t) word_address)();
}
This will only work for devices with up to 128KiB of flash memory!
The reason is that addresses in avr-g++ are 16 bits long, cf. the layout of void* as per avr-gcc ABI. This means using scalar addresses on devices with flash > 128KiB will not work in general, for example when you issue callFunctionAt (0x30000) on an ATmega2560.
On such devices, the 16-bit address in Z register used by EICALL instruction is extended by the value held in the EIND special function register, and you must not change EIND after entering main. The avr-g++ documentation is clear about that.
The crucial point here is how you are getting the address. First, in order to call and pass it around properly, use a function pointer:
typedef void (*func_t)(void);
void callFunctionAt (func_t address)
{
address();
}
void func (void);
void call_func()
{
func_t addr = func;
callFunctionAt (addr);
}
I am using void argument in the declaration because this is how you'd do it in C.
Or, if you don't like the typedef:
void callFunctionAt (void (*address)(void))
{
address();
}
void func (void);
void call_func ()
{
void (*addr)(void) = func;
callFunctionAt (addr);
}
If you want to call a function at a specific word address like, for example 0x0 to "reset"1 the µC, you could
void call_0x0()
{
callFunctionAt ((func_t) 0x0);
}
but whether this works depends on where your vector table is located, or more specifically, how EIND was initialized by the startup code. What will always work is using a symbol and define it with -Wl,--defsym,func=0 when linking with the following code:
extern "C" void func();
void call_func ()
{
void (*addr)(void) = func;
callFunctionAt (addr);
}
The big difference compared to using 0x0 directly it that the compiler will wrap symbol func with symbol modifier gs which it will not do when using 0x0 directly:
_Z9call_funcv:
ldi r24,lo8(gs(func))
ldi r25,hi8(gs(func))
jmp _Z14callFunctionAtPFvvE
This is needed if the address is out of the scope of EIJMP to advise the linker to generate a stub.
1 This will not reset the hardware. The best approach to force a reset is by letting the watchdog timer (WDT) issue a reset for you.
Methods
Yet another situation is when you want the address of a non-static method of a class because you also need a this pointer in that case:
class A
{
int a = 1;
public:
int method1 () { return a += 1; }
int method2 () { return a += 2; }
};
void callFunctionAt (A *b, int (A::*f)())
{
A a;
(a.*f)();
(b->*f)();
}
void call_method ()
{
A a;
callFunctionAt (&a, &A::method1);
callFunctionAt (&a, &A::method2);
}
The 2nd argument of callFunctionAt specifies which method (of a given prototype) you want, but you also need an object (or pointer to one) to apply it. avr-g++ will use gs when taking the method's address (provided the following call(s) cannot be inlined), thus it will also work for all AVR devices.
Based on comments I think you are asking about how microcontroller calls function.
Could you compile your program to see assembly files?
I would recommend you to read one of them.
Every function after compiling are translated to instructions that CPU can do (loading to register, adding to register etc.).
So then your void foo(int x) {statements;} compile to simple CPU instructions and whenever you call foo(x) in your program, you are moving to instructions that are related to foo - you are calling a subroutine.
As far as I remeber there is a CALL function in AVR to invoke subroutines and the name of subroutine is the label where executing program jump and invoking next instruction at adress.
I think you can clarify your doubts when you read some AVR assembly tutorials.
It is fun (at least for me) to see what exactly CPU do when it calls function that I wrote, but it required to know what instructions do. You develop in AVR so there is a set of instructions that you can read about in this PDF and compare with your assembly files.
I have a problem with QThread.
I did some calculation in GUI thread and it worked.
But now I try to do a calculation in work thread and there is a runtime error.
A have this function.
double **matrix(int nx,int ny, int shift)
{
int i;
double **m=(double **)calloc(nx+1, sizeof(double*));
for (i=0;i<=nx;i++) m[i]=(double *)calloc(ny+1,sizeof(double))+shift;
return m+shift;
}
And in run() function a want to do this:
double **lop=matrix(1,2,3);
But in this line there is this error: SIGSEGV Segmentation fault.
A don't understand, why the error is only in the work thread. Because when run this in GUI thread, it works.
Excuse me please my bad english.
You can't shift by 3. You must have things aligned to the word boundaries. Words are two bytes so the shift can only be an even number. Perhaphs you want
return m + shift*sizeof(double*);
I'm writing some signal processing routine, using the PortAudio library. I'm using a
stucture which contains a pointer to float which is intended to be used as a buffer. I then pass it to an audio callback function.
My problem is that after callback processing is finished, my pointer has changed reference and thus cannot be freed. This is not such a big deal but the thing is that I don't understand when and how the pointer reference is changed and I'm getting a feel like I'm missing something important.
Here is a simplified version of the code :
typedef struct{
float* tmp;
//other stuff
} Data;
Data data;
data.tmp = NULL;
data.tmp = (float*) calloc(N,sizeof(float));// N is the size of the buffer
Pa_OpenDefaultStream(some args, //opens a PortAudio stream and passes tmp to callback
callback,
&data );
A stream is then started in another high priority thread and the callback is being executed as many times as needed. During callback tmp is being used as a ring buffer and is constantly being copied new data to.
static int callback(args,void* data){
Data* x = (Data*) tmp;
x->tmp = update();
}
where update() returns a pointer to a float which is initialized the same way as tmp is (calloc).
float* update(){
//do stuff
return m_tmp2;
}
float* m_tmp2 = (float*) calloc(N,sizeof(float));//same N as before
But after the stream is closed I get an error when calling free before quitting.
free(data.tmp);//throws a SIGABRT error
Some breakpoint debugging showed me that the reference of the pointer is being changed during the callback processing, but I don't get when and how it happens because everything else runs smoothly. It must be something during the callback execution, but I'm sure update() returns a pointer that is the same size as tmp. Or is it link with PortAudio ?
Please, any clues ?
Not really sure if I understand it right. You allocated the float (x.tmp) every time the callback function is called..
static int callback(args,void* data){
Data* x = (Data*) tmp;
x->tmp = update();
}
I assume the above is typo, you actually mean
static int callback(args,void* data){
Data* x = (Data*) data;
x->tmp = update();
}
Well, you're actually change the pointer value of tmp by assigning it update() because it's reallocate a new memory location in heap and changed the pointing location of the tmp..
float* update(){
//do stuff
return m_tmp2;
}
The data.tmp must have pointed to a new location every time the callback function is called.. So, I don't see why it doesn't behave as you described..
That's the correct behavior already.. Maybe I miss anything?
and maybe you should provide a mechanism to keep track of the buffer.. so all tmp (float *) you allocate for your circular buffer can be freed (not just the first one before the first callback is called..
I'm using a project which uses the Eigen library. I've had to already fixed an issue where when using the data types provided by eigen within a STL, I get an align error
error C2719: '_Val': formal parameter with __declspec(align('16'))
won't be aligned
see
http://eigen.tuxfamily.org/dox/TopicStlContainers.html or -http://www.mrpt.org/Matrices_vectors_arrays_and_Linear_Algebra_MRPT_and_Eigen_classes)
Once this was fixed i could compile and run.
But now at run time I'm getting another error
Debug Error!
R6010
abort() has been called.
So the code in question references my structure and a vector of my structure (with the eigen specially aligned fix):
typedef struct {
Vector4f v4;
Matrix4f M4;
bool b;
} my_struct;
typedef std::vector<my_struct, Eigen::aligned_allocator<my_struct>> my_struct;
Then my code fails after a when I try to create a new my_struct after a certain number of iterations (it can sometimes creates the new object, with no problems), other times it fails.
for (int i = 0; i<len; i++) {
Vector4f vec;
Matrix4f mat;
my_struct* temp = new my_struct();
}
Any ideas?
Tom
Without -DNDEBUG, you should have got an assert sending you to this page. In your case, you should follow this one. In short, add EIGEN_MAKE_ALIGNED_OPERATOR_NEW to your structure such that new my_struct call an aligned memory allocator.