I am having trouble understanding this code and would like a good explanation.
The following function takes in a hex file and modifies the address without overwriting everything else.
Can someone explain to me how its doing that?
unsafe void WriteUint32(void* p, int Offset, uint value)
{
*(uint*)((byte*)p + Offset) = value;
}
If we ignore Offset, you have
*(uint*)((byte*)p) = value;
which is just assigning value to what p points to, interpreted as a uint.
Adding Offset just changes the pointer to where value is being assigned.
Related
I'm getting segmentation errors, when I define points in different objects which all point to the same variable. I also tried implementing it with shared pointers but so far it hasn't worked out. For example:
double var; //global var
int main(){
double *point_to_var = &var;
typeA A(point_to_var);
typeB B(point_to_var);
typeC C(point_to_var);
var = 10.;
B.sum(10.);
C.sum(10.);
}
struct typeA{
double *ptv;
A(double *ptvv): ptv(ptvv){}
}
struct typeB{
double *ptv;
B(double *ptvv): ptv(ptvv){}
double sum(double x);
}
struct typeC{
double *ptv;
C(double *ptvv): ptv(ptvv){}
double sum(double x);
}
double typeB::sum(double x){
return x + *ptv;
}
double typeC::sum(double x){
return x + *ptv;
}
I would have expected C.sum(10.) to return a value of 20 in this case, since *ptv points to the address of var which equals 10, however it crashes with a segmentation error. My code is more complicated than what I've shown here, but the idea is the same. It crashes when I try to use *ptv inside functions defined within objects. The code compiles on the command line, but on Xcode, inside of segmentation error I get exc_bad_access.
Using shared pointers (at least the way I did it) didn't seem to fix the problem. Is it possible to fix this without just using a global variable inside the objects?
I am learning the concept of pointer in C programming. I wrote a function as below to swap two adjacent nodes in a doubly-linked list;
void swapNode(DLListNode *a, DLListNode *b)
{
DLListNode *temp = a;
a->value = b->value;
b->value = temp->value;
}
and it doesn't work, as the value of b passes onto a successfully but, the value of a does not pass onto b. Then I found if I wrote the code like this, it works. Could someone please kindly explain the difference to me? Much appreciated.
void swapNode(DLListNode *a, DLListNode *b)
{
DLListNode temp = *a;
a->value = b->value;
b->value = temp.value;
}
The first version does not take a copy of the value that a points to. It merely creates a second reference to what a already references. When a->value gets a new value, then of course this is synonym to temp->value getting a new value.
In the second version, you create a node, which gets its properties from what a references. So here you do make a copy of a value property (and the next and prev properties). Now, when a->value gets changed, temp is unrelated to that change, and so temp.value is still what it was before that assignment to a->value. And that is exactly what you need to happen to make a successful swap.
It would even be possible to only copy the value property value, and not the node (which also has other properties like prev and next), since you really only need to have a copy of value; nothing else (I will assume here that value is an int):
void swapNode(DLListNode *a, DLListNode *b)
{
int value = a->value;
a->value = b->value;
b->value = value;
}
I was trying to figure this out for quite some time already, but I can't get it quite right. What I want to do is to round a float towards the nearest integer, based on a different float.
I basically need a function that should work like this:
float roundParam(float val, float dir)
{
if (dir >= 0)
return ceil(val);
else
return floor(val);
}
This is of course VERY inefficient, as it requires a branch per vector component. I figured this out, but it breaks for integers:
float roundParam(float val, float dir)
{
return round(val + 0.5 * sign(dir));
}
Thanks to #wim and his observation that floor(x) = -ceil(-x) and ceil(x) = -floor(-x) I was able to create this function that solved the problem:
float3 roundParam(float3 val, float3 dir)
{
float3 dirSign = sign(dir);
return dirSign * floor(dirSign * val) + dirSign;
}
In C you can use the following well vectorizable function. Maybe you can use the same idea in hlsl. This solution is only suitable if you don't care about the difference between +0 and -0 (signed zero) for dir.
float roundParam_v2(float val, float dir)
{
union fl_i32{float f; int i;} x, y, d;
x.f = val;
d.f = dir;
d.i = d.i & 0x80000000; /* extract the sign bit */
x.i = x.i ^ d.i; /* multiply x 1.0f if signbit is set */
y.f = ceilf(x.f); /* note that floor(z) = - ceil( -z) */
y.i = y.i ^ d.i; /* multiply x 1.0f if signbit is set */
return y.f;
}
How about:
float roundParam(float val, float dir)
{
return ceil(val)*(float)(dir>=0)+floor(val)*(float)(dir<0);
}
It can be probably be further optimized, but that optimization is probably already made by the compiler.
Btw, if you add the [flatten] tag to the if conditional, it probably already gets optimized by the compiler. And for such a simple branch, it is most probably already flattened by the compiler whether you tag it or not.
It would be interesting to check the compiled code and see if the branch has already been removed. I’m currently afk so I cannot check...
Perhaps use an array of pointers selected by dir?
Below is C. Unclear how usable such an approach is in hsl, shader
float roundParam(float val, float dir) {
static float (*f[2])(float) = {ceilf, floorf};
return f[!!signbit(dir)](val);
}
Per the Go tour page 28 and page 53
They show a variable that is a pointer to a struct literal. Why is this not the default behavior? I'm unfamiliar with C, so it's hard to wrap my head around it. The only time I can see when it might not be more beneficial to use a pointer is when the struct literal is unique, and won't be in use for the rest program and so you would want it to be garbage collected as soon as possible. I'm not even sure if a modern language like Go even works that way.
My question is this. When should I assign a pointer to a struct literal to a variable, and when should I assign the struct literal itself?
Thanks.
Using a pointer instead of just a struct literal is helpful when
the struct is big and you pass it around
you want to share it, that is that all modifications affect your struct instead of affecting a copy
In other cases, it's fine to simply use the struct literal. For a small struct, you can think about the question just as using an int or an *int : most of the times the int is fine but sometimes you pass a pointer so that the receiver can modify your int variable.
In the Go tour exercises you link to, the Vertex struct is small and has about the same semantic than any number. In my opinion it would have been fine to use it as struct directly and to define the Scaled function in #53 like this :
func (v Vertex) Scaled(f float64) Vertex {
v.X = v.X * f
v.Y = v.Y * f
return v
}
because having
v2 := v1.Scaled(5)
would create a new vertex just like
var f2 float32 = f1 * 5
creates a new float.
This is similar to how is handled the standard Time struct (defined here), which is usually kept in variables of type Time and not *Time.
But there is no definite rule and, depending on the use, I could very well have kept both Scale and Scaled.
You're probably right that most of the time you want pointers, but personally I find the need for an explicit pointer refreshing. It makes it so there's no difference between int and MyStruct. They behave the same way.
If you compare this to C# - a language which implements what you are suggesting - I find it confusing that the semantics of this:
static void SomeFunction(Point p)
{
p.x = 1;
}
static void Main()
{
Point p = new Point();
SomeFunction(p);
// what is p.x?
}
Depend on whether or not Point is defined as a class or a struct.
Sorry for the vague title.
Currently, if a value is typed into a Q(Double)SpinBox which is out of its range (e.g. typing "100" when max is 90), the value is rejected and instead the last valid value is placed back into the SpinBox.
I want to change this behavior to allow typing out-of-range values which will be automatically corrected (to either the minimum or maximum), because otherwise it would be stupidly hard for the user to guess the value range. After studying the docs and source code of QT, I decided to subclass QSpinBox (will deal with Double variant later) into "QSpinBoxFS", and reimplement both methods mentioned in the title. Somehow though, this is having no effect at all, the behavior is still the same.
These are my methods:
QValidator::State QSpinBoxFS::validate(QString &input,
int &pos)
{
QIntValidator *validator = new QIntValidator();
return validator->validate(input, pos);
}
int QSpinBoxFS::valueFromText(const QString &text)
{
const int max = maximum();
const int min = minimum();
QString copy = text;
int dummy = 0;
QValidator::State state = validate(copy, dummy);
if (state == QValidator::Acceptable)
{
bool ok;
int num = locale().toInt(text, &ok, 10);
if (!ok) { goto bad_text; }
if (num < min) { return min; }
if (num > max) { return max; }
return num;
}
else
{
bad_text:
return (max > 0) ? min : max;
}
}
Of course, this is not really adequate to the pedantic checking done in QSpinBoxPrivate::validateAndInterpret, but I just want the basic concept working for now.
I tried changing validate() to always return Acceptable, but weirdly enough the resulting spinboxes would still behave in the old way.
Either a correction of my own methods or a different approach to this problem are welcome! Thank you for your time.
The signatures of the methods you're trying to reimplement are:
QValidator::State validate(QString & input,int & pos) const # <- const!
int valueFromText(const QString & text) const # <- const!
Both your methods are missing the const, so they are different methods and thus never called from the base class.
On a different note,
QAbstractSpinButton::setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue)
can achieve somehwat similar results (typing values smaller than min will be corrected to min), although you are still prevented from typing values greater than max due to the validator. (And therefor it is insufficient for my needs, just leaving it here for reference.)