I'm trying to understand why method1 works, and method2 doesnt work, when I'm passing "offset" to SDL_BlitSurface function.
USAGE:
int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
In my mind, both should work, since SDL_BlitSurface function asks SDL_Rect* as the 4th input argument. And in both cases I have passed a SDL_Rect* to the function. However method2 yields "Unhandled exception Access violation writing location error". Please help!
method1:
SDL_Rect offset;
offset.x = 1;
SDL_BlitSurface( source, NULL, destination, &offset );
method2:
SDL_Rect* offset = NULL;
offset->x = 1;
SDL_BlitSurface( source, NULL, destination, offset );
(Code from Lazy Foo's tutorial Lesson 2)
A pointer variable (like offset) holds an address, just like a house address.
The structure tells the computer who lives in the house in each room (the rooms have names, for example x).
The problem is that you first say: "offset is a fake address (call it NULL)." and then you say "and in room x lives 1". So this doesn't make sense - the number 1 can live in room x only if the address is real. Nobody can live in a fake address.
Unfortunately, you can write whatever you want in the code. Only when you run it and try to put 1 in room x the computer shouts. "Access violation" basically means: "you're trying to put some data in an address that you don't have access to". In this case, the fake address NULL is not an address you can store anything in.
If you follow Armin's suggestion, then offset will point to a valid address, and that will allow you to store 1 in the room x. Method 1 solves the problem by passing the address of a pre-allocated structure offset (it's allocated automatically by the compiler on the stack).
In the second case you haven't reserved any memory for offset since SDL_Rect* offset is just a pointer, you have to allocate memory for it to point to something:
Example in c:
SDL_Rect* offset = malloc( sizeof( SDL_Rect ) );
Then you second method will work.
Related
I am a bit confused about passing by reference and value in Go.
I've seen this explained of the * in front of a type.
in front of a type name, means that the declared variable will store an address of another variable of that type (not a value of that
type).
This just doesn't make sense to me.
In Java if I was passing a Database instance into a function I would do
databaseFunction(DatabaseType db) {
// do something
}
However in the go example I have it's passed like so.
func PutTasks(db *sql.DB) echo.HandlerFunc {
}
Why do we need to have the asterisk in front of the type?
According to this cheat sheet, I found.
func PrintPerson(p *Person) ONLY receives the pointer address
(reference)
I don't understand why I would only want to send a pointer address as a parameter.
First, Go technically has only pass-by-value. When passing a pointer to an object, you're passing a pointer by value, not passing an object by reference. The difference is subtle but occasionally relevant. For example, you can overwrite the pointer value which has no impact on the caller, as opposed to dereferencing it and overwriting the memory it points to.
// *int means you *must* pass a *int (pointer to int), NOT just an int!
func someFunc(x *int) {
*x = 2 // Whatever variable caller passed in will now be 2
y := 7
x = &y // has no impact on the caller because we overwrote the pointer value!
}
As to your question "Why do we need to have the asterisk in front of the type?": The asterisk indicates that the value is of type pointer to sql.DB, rather than a value of type sql.DB. These are not interchangeable!
Why would you want to send a pointer address? So that you can share the value between the caller of a function and the function body, with changes made inside the function reflected in the caller (for example, a pointer is the only way that a "setter" method can work on an object). While Java passes objects by reference always, Go passes by value always (i.e. it creates a copy of the value in the function); if you pass something to a function, and that function modifies that value, the caller won't see those changes. If you want changes to propogate outside the function, you must pass a pointer.
See also: the Go tour section on Pointers, the Go spec section on pointers, the Go spec section on the address operators
The purpose of reference semantics is to allow a function to manipulate data outside its own scope. Compare:
func BrokenSwap(a int, b int) {
a, b = b, a
}
func RealSwap(a *int, b *int) {
*a, *b = *b, *a
}
When you call BrokenSwap(x, y), there is no effect, because the function receives and manipulates a private copy of the data. By contrast, when you call RealSwap(&x, &y), you actually exchange the values of the caller's x and y. Taking the address of the variables explicitly at the call site informs the reader that those variables may be mutated.
Pass by Reference :-
When you pass a same variable into a function by different name.
Below example from C++ (as Go doesnt have this concept), where a and a1 are same variable.
void swap(int& a1, int& b1)
{
int tmp = a1;
a1 = b1;
b1 = tmp;
}
int main()
{
int a = 10, b = 20;
swap(a, b);
cout << "a " << a << " b " << b ;
}
Go passes everything as data( means it copies the data from current active frame to new active frame of new function). So if you pass values it copies the value and advantage is safety from accidental modification. And when it passes address of variable its copied also into the new pointer variables but has advantage of efficiency since size of pointer is smaller.
Following this link, I try to understand the operating of kernel code (there are 2 versions of this kernel code, one with volatile local float *source and the other with volatile global float *source, i.e local and global versions). Below I take local version :
float sum=0;
void atomic_add_local(volatile local float *source, const float operand) {
union {
unsigned int intVal;
float floatVal;
} newVal;
union {
unsigned int intVal;
float floatVal;
} prevVal;
do {
prevVal.floatVal = *source;
newVal.floatVal = prevVal.floatVal + operand;
} while (atomic_cmpxchg((volatile local unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal);
}
If I understand well, each work-item shares the access to source variable thanks to the qualifier "volatile", doesn't it?
Afterwards, if I take a work-item, the code will add operand value to newVal.floatVal variable. Then, after this operation, I call atomic_cmpxchg function which check if previous assignment (preVal.floatVal = *source; and newVal.floatVal = prevVal.floatVal + operand; ) has been done, i.e by comparing the value stored at address source with the preVal.intVal.
During this atomic operation (which is not uninterruptible by definition), as value stored at source is different from prevVal.intVal, the new value stored at source is newVal.intVal, which is actually a float (because it is coded on 4 bytes like integer).
Can we say that each work-item has a mutex access (I mean a locked access) to value located at source address.
But for each work-item thread, is there only one iteration into the while loop?
I think there will be one iteration because the comparison "*source== prevVal.int ? newVal.intVal : newVal.intVal" will always assign newVal.intVal value to value stored at source address, won't it?
I have not understood all the subtleties of this trick for this kernel code.
Update
Sorry, I almost understand all the subtleties, especially in the while loop :
First case : for a given single thread, before the call of atomic_cmpxchg, if prevVal.floatVal is still equal to *source, then atomic_cmpxchg will change the value contained in source pointer and return the value contained in old pointer, which is equal to prevVal.intVal, so we break from the while loop.
Second case : If between the prevVal.floatVal = *source; instruction and the call of atomic_cmpxchg, the value *source has changed (by another thread ??) then atomic_cmpxchg returns old value which is no more equal to prevVal.floatVal, so the condition into while loop is true and we stay in this loop until previous condition isn't checked any more.
Is my interpretation correct?
If I understand well, each work-item shares the access to source variable thanks to the qualifier "volatile", doesn't it?
volatile is a keyword of the C language that prevents the compiler from optimizing accesses to a specific location in memory (in other words, force a load/store at each read/write of said memory location). It has no impact on the ownership of the underlying storage. Here, it is used to force the compiler to re-read source from memory at each loop iteration (otherwise the compiler would be allowed to move that load outside the loop, which breaks the algorithm).
do {
prevVal.floatVal = *source; // Force read, prevent hoisting outside loop.
newVal.floatVal = prevVal.floatVal + operand;
} while(atomic_cmpxchg((volatile local unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal)
After removing qualifiers (for simplicity) and renaming parameters, the signature of atomic_cmpxchg is the following:
int atomic_cmpxchg(int *ptr, int expected, int new)
What it does is:
atomically {
int old = *ptr;
if (old == expected) {
*ptr = new;
}
return old;
}
To summarize, each thread, individually, does:
Load current value of *source from memory into preVal.floatVal
Compute desired value of *source in newVal.floatVal
Execute the atomic compare-exchange described above (using the type-punned values)
If the result of atomic_cmpxchg == newVal.intVal, it means the compare-exchange was successful, break. Otherwise, the exchange didn't happen, go to 1 and try again.
The above loop eventually terminates, because eventually, each thread succeeds in doing their atomic_cmpxchg.
Can we say that each work-item has a mutex access (I mean a locked access) to value located at source address.
Mutexes are locks, while this is a lock-free algorithm. OpenCL can simulate mutexes with spinlocks (also implemented with atomics) but this is not one.
Below is code and I want to ask, why I am not getting swapped number as a result, because instead of swapping numbers I tried to swap their addresses.
int *swap(int *ptr1,int *ptr2){
int *temp;
temp = ptr1;
ptr1= ptr2;
ptr2=temp;
return ptr1,ptr2;
}
int main(){
int num1=2,num2=4,*ptr1=&num1,*ptr2=&num2;
swap(ptr1,ptr2);
printf("\nafter swaping the first number is : %d\t and the second number is : %d\n",*ptr1,*ptr2);
}
I can see two problems in your code.
First, within the swap function, ptr1 and ptr2 are local copies of the pointers in main with the same name. Changing them in swap only changes those copies, not the originals.
Second, the return statement doesn't do anything useful. The function swap is declared as returning a single int *. The return statement actually only returns ptr2 - for why that is, look up the "comma operator" in C. But you ignore the return value in main anyway, so it makes no odds.
I'm new to pointers and realloc. I know what is going wrong, but I don't know how to solve it.
I create a struct with an array of pointers:
struct DB_SLOT
{
MYSQL *MYSQL_Connection[10];
char *DB_NAME_Connection[10];
};
struct DB_SLOT DB_Conn_SLOT;
I allocate memory with realloc in a loop and (this is where it is getting wrong) I print the address of pointer 2 on the screens.
If I then try to realloc the same amount of memory (just for test purposes). it gives a glibc invalid pointer. Before realloc I print the address of pointer 2 again and it is not the same.
The code for this:
int MallocLoop;
for (MallocLoop = 0;MallocLoop < 10;MallocLoop++)
{
DB_Conn_SLOT.MYSQL_Connection[MallocLoop] = realloc(DB_Conn_SLOT.MYSQL_Connection[MallocLoop],(sizeof(MYSQL)));
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]=realloc(DB_Conn_SLOT.DB_NAME_Connection[MallocLoop],(sizeof(char)));
if (MallocLoop == 2)
{
printf("pointer 1 %d \n",DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]);
}
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] ="\0";
}
MallocLoop = 2;
printf("pointer 2 %d \n",DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]);
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] = realloc(DB_Conn_SLOT.DB_NAME_Connection[MallocLoop], (sizeof(char)));
The result of printing the address of the pointer results in 2 different addresses. How do i solve this??
You have the following two lines:
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]=realloc(...); ...
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] ="\0";
Let's simplify this to:
p = realloc(...);
p = "\0";
The first line makes p point at dynamically allocated memory block. The second line leaks that memory (you no longer have a pointer to it), and makes p point to a block of memory inside the .data section.
When you loop again, and pass the .data pointer to realloc, it correctly complains: it is not valid to pass non-dynamically allocated memory to realloc.
What you probably wanted to do was this:
p = realloc(...);
p[0] = '\0';
That makes p point to a dynamically allocated memory block, and makes that block be an empty string.
I just want to get a better understanding of what a stack is in the address space (i.e you have code/text, heap, data, and a stack)
basically my understanding is that a stack contains local variables, but then what is the difference between what the data contains and what a stack contains? isn't data variables as well?
If a program has a recursive call to a function a() does it mean that for every level of recursion there is a new stack?
A stack is usually different to data only in the way it's used and managed. While non-local variables themselves usually have a known specific memory location, things on the stack are found relative to a register (stack pointer or base pointer or some such).
A stack usually contains local variables, passed parameters and control information for managing the stack itself.
And, if you make a recursive call, you don't get a new stack, just a new stack frame. A frame is a chunk of the stack relevant to the current stack depth (whether that's by recursion or just regular function calls). That's what makes recursion possible, the fact that the variables for a given depth are independent of those for other depths.
Keep in mind that this is all dependent, of course, on the architecture. My description above is a common case but there are architectures where stacks are done differently, such as SPARC, the System z and RCA1802.
More details can be found here (how frames work) and here (weird stacks).
First, a small clarification. Stacks are not necessarily in DRAM. they are just a structure that can be formed in any memory: DRAM, caches, disk.
To understand a stack, you should first understand what is a stack. It is like a stack of trays, the properties that make it a stack are:
You can only access the top element of the stack
It is Last In First Out, i.e., when you go to get a data from a stack you get the data that was stored last on the stack.
The act of storing something in a stack is called PUSH and removing it is called a POP. Say I do the following to an empty stack:
PUSH A
PUSH B
PUSH C
Then the stack will contain
C - Top
B
A
Now if I execute a POP (notice there is no operand here), it will return C and the stack will contain
B -- top of stack
A
So stack in processors is just a hardware implementation of the above algorithm.
A register contains the address of the top of stack called stack point
The ISA (Instruction Set Architecture) provides PUSH and POP instructions to access the stack variables as I showed above.
This is a very useful construct. A stack is used to store local variables, basically temporary data that you want to remove at the end of a function call. It specifically helps with function calls. When a function is called, the variables of the newly called function's local variables are pushed on the stack.
foo(){
int a;
int b; // both registers containing a and b are PUSHed here on the stack
c = bar(); // pop the stack to get value of c
print c
}
bar(){
int z; // local variables pushed on top of the stack
z = ...
return z; // pop all local variables of bar(), then push z on the stack
}
I hope the above helps.
The following program should help you understand what is going on. You will see pointer examples of text, bss, heap, and stack. Text is usually executable code, bss are static/global variables, heap is dynamically allocated memory, stack contains local variables.
#include <stdlib.h>
#include <stdio.h>
#define TESTS 10
int numfeed = 0;
int numdead = 0;
recurse(int x)
{
u_int pattern=0xfeedface;
u_int *otherpattern = malloc(4);
*otherpattern = 0xdeadbeef;
printf("Feedface %d is at %p\n",x,&pattern);
printf("deadbeef %d is at %p\n",x,otherpattern);
if (--x == 0)
{
int *off;
for(off = &pattern;numfeed<TESTS;off++)
{
if (*off == 0xfeedface)
printf("Found feedface #%d at %p\n", ++numfeed, off);
if (*off == 0xdeadbeef)
printf("Found deadbeef #%d at %p -- WHAT?!?!!?!?\n", ++numdead, off);
}
}
else
{
recurse(x);
}
// Not freeing otherpattern intentionally.
}
main()
{
u_int *otherpattern = malloc(4);
*otherpattern = 0xdeadbeef;
int *off;
recurse(TESTS);
for(off = otherpattern+1;numdead<TESTS;off++)
{
if (*off == 0xfeedface)
printf("Found feedface #%d at %p -- WHAT?!?!!!?!?\n", ++numfeed, off);
if (*off == 0xdeadbeef)
printf("Found deadbeef #%d at %p\n", 1+TESTS-(++numdead), off);
}
printf("numfeed is at %p\n",&numfeed);
printf("recurse is at %p\n",&recurse);
}