what is the effect of *pe=pn->Entry;? - c

All I need to understand is what is that line mean:
*pe=pn->Entry;
Why can't I skip it.how does it affect the serve operation?
void Serve(Entrytype *pe,Queue *pq){
QueueNode *pn;
*pe=pn->Entry;
pn=pq->front;
pq->front=pn->next;
free(pn);
}

It doesn't affect the function itself, however it essentially acts as a return value, setting a value outside the function denoted by the pointer for later use. So, if you omit the line, the function will still work, but what comes after the function might not.

This is a common C technique to allow for mutable arguments. A typical case looks like this:
void mutate(int* a) {
*a = 5;
}
Where when called:
int main() {
int a = 0;
mutate(&a);
printf("a=%d\n", a);
return 0;
}
Will now show that a has been altered.
If this were a non-pointer argument, like this:
void mutate(int a) {
a = 5;
}
Then you're only changing the local variable a and it has no effect on the caller's variable.

Related

how to return a pointer value from function to array of strings in c? [duplicate]

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.

Retrieve return value of function pointer, which is provided as parameter to other function

This might be a bit specific, but I want to know, how to return a ... let's see the code first actually.
void *atomic_op(void * (*f)(),void* ret) // Using a function pointer to encapsulate the procedure in between locks
{
pthread_mutex_lock(&mut1);
ret = f;
pthread_mutex_unlock(&mut1);
}
I want to be able to get the return value of f and store it to ret using void pointers for more general use.
My IDE informs me that argument ret is not accessed outside the scope of this function, but later down my code there is
char* temp;
while (1)
{
atomic_op(readBuffer(shared_array),temp);
if (*temp == 0)
{
break;
}
atomic_op(printOutBuffer(shared_array),NULL);
}
When running the whole thing, the IDE comes our right (of course) but I cannot understand why.
The whole thing is an attempt on monitors, with 2 threads sharing an array in a consumer producer relationship (just experimenting) and I stumbled across this which I found really weird!
Can someone explain what happens here?
The whole thing is here https://controlc.com/2af8f50c
Link with pthread
First off, this doesn't actually call the function:
ret = f;
It just takes the function pointer and assigns it to ret. To call the function you want f().
Also, because parameters in C are passed by value, changes to the parameter ret aren't reflected in the calling function. That fact that ret is a pointer type doesn't matter.
If you want a function to update a pointer value it needs to take a pointer to a pointer. That pointer-to-pointer parameter must then be dereferenced to update the pointer variable in the calling function.
Making these fixes, your function would look like this:
void *atomic_op(void * (*f)(),void **ret)
{
pthread_mutex_lock(&mut1);
if (ret) {
*ret = f();
}
pthread_mutex_unlock(&mut1);
}
And you would call it like this:
char *tmp;
void *tmp2;
atomic_op(readBuffer(shared_array),&tmp2);
tmp = tmp2;
Here the extra void * variable is required because a char ** is not guaranteed to be safely converted to a void **.
There's still one thing we haven't addressed, and that's that the function is defined to return a void * but doesn't actually return anything. This is OK for your program since you're not attempting to access the return value, but still it's a bad code smell.
It would be better to take the return value of f and make that the return value of atomic_op and get rid of the second parameter. This also means you don't need a second variable in the calling function.
So now we have:
void *atomic_op(void * (*f)())
{
void *ret;
pthread_mutex_lock(&mut1);
ret = f();
pthread_mutex_unlock(&mut1);
return ret;
}
Which would be called like this:
char *tmp;
tmp = atomic_op(readBuffer(shared_array));
All this is assuming that readBuffer and printOutBuffer return function pointers. If they don't, you need to pass just the name of the function and the function's parameters to atomic_op, and the type of f would need to match the type of readBuffer and printOutBuffer. That would give you:
void *atomic_op(void *(*f)(void *), void *param)
{
void *ret;
pthread_mutex_lock(&mut1);
ret = f(param);
pthread_mutex_unlock(&mut1);
return ret;
}
Which is called like this:
char *tmp;
tmp = atomic_op(readBuffer, shared_array);

Accessing variables in another function without the variable being in the function parameter

void foo() {
int i = 3;
bar();
}
void bar() {
//print i in foo()
}
I was wondering if there is some way that I could do this without setting a global variable?
No, this is a local variable and is stored in the stack for that method, outside that method the stack does not exist and can not be read
If you want to just use the value of i, you can use:
void bar(int i);
void foo() {
int i = 3;
bar(i);
}
void bar(int i) {
//print i in foo()
}
If you want to be able modify the value of i, use:
void bar(int* ip);
void foo() {
int i = 3;
bar(&i);
}
void bar(int* ip) {
*ip = 20;
}
C uses static scoping. You can check this here: https://msujaws.wordpress.com/2011/05/03/static-vs-dynamic-scoping/ :)
Simply pass i from foo to bar as parameter:
bar(i);
void bar(int i)
You can, but you have to pass it to foo as an argument. The reason for this is that when a C function is called it creates any local variables defined inside it on the stack, which is essentially just a form of dynamic memory allocation. When the function returns, it frees the memory used by those variable. Now you might think there should be some way for bar to know about i since it is still present on the stack when bar is called inside foo. But the problem is that C does not make any assumptions about who might be calling the bar function. You could just as easily call bar from a third function that has no i defined within it. For this reason there is no mechanism for accessing stack variables from a nested function without passing them explicitly.
Interestingly, having the ability to do this built into the language is one of the key features that allows for the implementation of closures. So if you have ever struggled to understand what made these so special, this is basically it. Probably not as spectacular as the hype might have lead you to believe.

How to update a variable using a function with no arguments and no return type in C

I know that If a function has no argument & only return type (say int), then I can change my int variable by assigning the function to my variable as below,
main()
{
int var_name;
var_name = func();
printf("My variable value is updated as : %d", a);
}
func()
{ return 100; }
Also I know that If I have my function's return type as void, with no arguments, then I can only print the value inside the function itself and cannot return anything in turn.
But, my doubt is, is there anything else that I can do to update my var_name by calling a function with no arguments & no return type ?
ie., void func(void); by using something like pointer concepts ??
I could not able to find the exact answer for the same by my searches among so many websites.. I will be very grateful if someone can help me out finding whether I can do it by this way or not,.
Thanks,.
It is possible to modify a local variable in main, from a function with no arguments and no return value, if there's a global pointer to it:
#include <stdio.h>
int *p;
void func() {
*p = 6;
}
int main() {
int a = 5;
p = &a;
func();
printf("a = %d\n", a); // prints: a = 6
return 0;
}
There's no good way to do that. If you want the function to modify a local variable, you should probably change the function so it either returns a value that you can assign to the variable, or takes the variable's address as an argument.
But if you don't mind writing some ugly code, you can define a global (file-scope) pointer variable, assign the local variable's address to the global pointer, and then use that to modify the variable inside the function.
An example:
#include <stdio.h>
int *global_pointer;
void func(void) {
*global_pointer = 42;
}
int main(void) {
int local_variable = 0;
global_pointer = &local_variable;
func();
printf("local_variable = %d\n", local_variable);
}
It's very easy to shoot yourself in the foot his way. For example, if you refer to the pointer after the calling function has terminated (and the local variable no longer exists), you'll have undefined behavior.
This technique can actually be useful if you need to make a quick temporary change in a body of code in which you can't make major interface changes. Just don't do it in code that will be maintained by anyone else -- and wash your hands afterward.
You can have global variable
int var_name;
void func();
int main()
{
func();
printf("%d\n",var_name);
}
void func()
{
var_name = 20;
}
But if your variable is local to main() then this can't be done.
There are two ways to modify the value of var_name.
Make changes in the calling function and return the value.( which you have already shown)
Pass the address of the var_name to the function and have pointer as arguement in the func(int *p) and modify the value inside the func()
Thats it!! No other way this can be done.

How to return a value to the calling function without using return statement?

The function proto type like int xxxx(int) or void xxx(int)
You could use a global variable (or, a little better, you could use a static variable declared at file scope), or you could change your functions to take an output parameter, but ultimately you should just use a return statement, since that's really what it's for.
The two standard ways to return values out of functions in C are to either do it explicitly with the return statement, or to use a pointer parameter and assign into the object at the pointer.
There are other ways, but I'm not going into them for fear of increasing the amount of evil code in the world. You should use one of those two.
Use pass by reference:
void foo(int* x, int* y) {
int temp;
temp = *x;
x* = *y;
y* = temp;
}
void main(void) {
int x = 2, y=4;
foo(&x, &y);
printf("Swapped Nums: %d , %d",x,y);
}
You could have a global variable that you assign the value to.
You could pass an object that stores the integer, and if you change it in the function, it'll change elsewhere too, since objects are not value type.
It also depends on the programming language that you're using.
EDIT: Sorry I didn't see the C tag, so ignore my last statement
Typically you provide a reference to an external variable to your function.
void foo(int *value)
{
*value = 123;
}
int main(void)
{
int my_return_value = 0;
foo(&my_return_value);
printf("Value returned from foo is %d", my_return_value);
return 0;
}
The simple answer is given a prototype like the first one you must use the return statement as the int return value dictates it.
In principle it is possible to do something horrible like cast a pointer to an int and pass it in as a parameter, cast it back and modify it. As others have alluded to you must be sure you understand all the implications of doing this, and judging by your question I'd say you don't.
int wel();
int main()
{
int x;
x = wel();
printf("%d\n",x);
return 0;
}
int wel()
{
register int tvr asm ("ax");
tvr = 77;
}
Compiled with GCC compiler in ubuntu machine. In borland compiler, different way to return.
If you need to return more than one value, why not use a pointer to a new allocated struct?
typedef struct { int a, char b } mystruct;
mystruct * foo()
{
mystruct * s = (mystruct *) malloc(sizeof(mystruct));
return s;
}
Not tested, but should be valid.

Resources