Modify argument without return - c

I have a problem in C. I have this function :
int test(void *data);
I want to change data with this function but I don't want another prototype (not use void **). Actualy, data equals null out this function.
#include <stdio.h>
#include <stdlib.h>
int
test(void *data)
{
data = "toto";
return 1;
}
int
main()
{
void *d;
if (test(d) != 1) {
printf("erreur\n");
}
printf("résultat : %s\n", (char *) d); // displays "résultat : (null)"
return 0;
}
Help me please. ;)

In C arguments to function are passed by value. d is passed by value to function test. data is a local variable to function test and d is copied to data. The assignment
data = "toto";
makes pointer data to point to string literal toto, while d is unaffected of this assignment in main function. So, this assignment has no effect on d.
In main you are dereferencing an uninitialized pointer. This will result in undefined behavior.

In your test function, you change data, which doesn't affect d because data is just a local variable. If you really need to change d, then you need to let test return data and do d=test(d).
Moreover, in your test function, the value of data is never used. So what is the point to have data as a parameter of the function?
In printf("résultat : %s\n", (char *) d);, you try to cast d into pointer to char and then print the value of d. Although you don't dereference d, you are still printing a variable that hasn't been initialized, which is undefined behavior.

Any object pointer (i.e. non-function pointer) can be converted to a void * and back to the original type without altering the value. This means that you can pass any kind of (object) pointer to your test() function, it will be automatically converted to a void *, and you can then convert it back inside test().
#include <stdio.h>
int test(void *data)
{
char **s = data;
*s = "toto";
return 1;
}
int main()
{
char *res;
if (test(&res) != 1) {
printf("erreur\n");
}
printf("résultat : %s\n", res);
return 0;
}
You just need to make sure that the test() function knows what the original type was.

Related

double pointers error in C when compiling error when using void as well

I'm new to C and im currently learning about pointers.
I'm not sure why I am getting an error with the following sections of code in regards to pointers :
char ch;
char** pointer;
pointer = &ch;
and
int function1(void)
{
return 42.0;
}
void function2(void)
{
void (*pointer)(int);
pointer = &function1;
...
}
Any help will be appreciated :)
The very first problem is that you are using a double pointer in char** pointer ,as you are not storing the address of some other pointer so you should use char *pointer instead.
Then your function1 has return type as int but you are returning a float value ,although it won't give you any error but it can create some logical issues in your program,so better to properly write the return type in function definition and its prototype.
Then the next problem is in the function2,your function1 returns int but does not take any arguments but your function pointer return void and take int ,so you should better modify this to
int (*pointer)(void);
and then store the address of function1 in pointer ,it will work fine.
* is a single pointer and ** is a pointer to pointer.
So instead of
char** pointer;
It should be:
char* pointer;
In the second case, the function pointer prototype is not matching the prototype of the function it is pointing to.
So instead of
void (*pointer)(int);
it should be:
int (*pointer)(void);
you second section have some mistakes
you function1() return int and not take args
but your fucntion ptr return void and take int
so change it to:
int (*pointer)(void);
pointer = &function1;

passing address of variable to function

I am not great on pointers but I have to learn in the field. If my understanding serves me correct these should all be valid statements below.
int* a;
int b = 10;
a = &b;
(*a) = 20;
(*a) == b; //this should be true
if you have a function like this:
void copy(int* out, int in) {
*out = in;
}
int m_out, m_in;
copy(&m_out, m_in);
m_out == m_in; // this should also be true
but I saw a function like this
create(float& tp, void* form, char* title);
I understand the void pointer, it can be cast to anything, I understand the character pointer which is basically a c style string.
I do not understand the first argument, which is the address of some type, let's say a float but it could be anything, a struct, a int, etc.
What is going on there?
First this
int m_out, m_in;
copy(&m_out, m_in);
is undefined behaviour - you passed uninitialized vaiable m_in to function - and hence trying to make copy of an uninitialized variable.
This:
create(float& tp, void* form, char* title);
doesn't make sense in C. Looks like reference from C++.
The first argument is a reference, it just means that if you modify this field in your function create, the field will still remain modified (even in the function where you called create()) because it points to an address and not a value.

How to store result of type char in pointer?

I want to store result of type char in pointer which I'm passing as argument of function. Like this:
#include<stdio.h>
void try(char *);
int main()
{
char *result;
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
result="try this";
}
But I'm getting result : (null)
Could someone tell me what's wrong here?
Your syntax only sends the pointer to the function. This allows changing the data the pointer points to, but not the pointer itself.
You would need to have
void try(char **result)
and call it
try(&result);
to change the actual pointer.
Another way is to copy data into the memory pointed by the pointer, but then you need to know there is enough memory available. Depends on the actual use case how to do it properly. You might use
strcpy(result, "what you want");
but then you really have to know that the memory pointed by result can handle 14 chars (remember the NULL in the end). In your current code you don't allocate memory at all for result, so this will invoke undefined behaviour.
The reason you're seeing NULL is because your compiler decided to initialize non-assigned pointers to NULL. Another compiler might initialize them to random values.
Also about terminology, you're not storing type char into a pointer. You may have a pointer pointing to a char, or in this case to a C type string, which is an array of chars.
You are creating another variable result inside try function.
Try printing result inside try function. It will work then.
If you really want to print inside main then try this -
#include<stdio.h>
void try(char **);
int main()
{
char *result;
try(&result);
printf("%s",result);
return 0;
}
void try(char** result)
{
*result = "try this";
//printf("%s\n",result);
}
Or if you don't want to get into double pointers, then this will work:
#include<stdio.h>
char* try(char *);
int main()
{
char *result;
result = try(result);
printf("%s",result);
return 0;
}
char* try(char* result)
{
result = "try this";
return result;
}
Also another way (no dynamic memory):
#include<stdio.h>
void try(char *);
int main()
{
char result[100] = {0};
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
strcpy(result,"try this");
}
Note: When you say you got null, that doesn't mean anything - actually you had undefined behaviour there - because result was not initialized. I guess you invoked UB even before trying to print result, namely when you passed it to try. Because copy would be made in that method of the pointer, which would try to read value of original pointer - reading uninitialized variables is undefined in C. Hence always initialize your variables in C.

C Function implementation - with Pointer vs without Pointer

I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string.
pointerstring vs normal.
Also if you want to provide more information about when to use pointers that would be great. I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value.
#include <stdio.h>
void pointerstring(char *s);
void normal(char s[]);
int main() {
char string[20];
pointerstring(string);
printf("\nPointer: %s\n",string);
normal(string);
printf("Normal: %s\n",string);
}
void pointerstring(char *s) {
sprintf(s,"Hello");
}
void normal(char s[]) {
sprintf(s,"World");
}
Output:
Pointer: Hello
Normal: World
In a function declaration, char [] and char * are equivalent. Function parameters with outer-level array type are transformed to the equivalent pointer type; this affects calling code and the function body itself.
Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt e.g. to take the sizeof of an outer-level fixed-length array type parameter:
void foo(char s[10]) {
printf("%z\n", sizeof(s)); // prints 4 (or 8), not 10
}
When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const), you are explicitly giving the function permission to modify the object or array the pointer points to.
One of the problems in C is that arrays are second-class citizens. In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information).
Therefore, it makes no difference whether you take an array as T* arg or T arg[] — the latter is a mere synonym for the former. Both are pointers to the first character of the string variable defined in main(), so both have access to the original data and can modify it.
Note: C always passes arguments per copy. This is also true in this case. However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address, so that the object referred to is accessible through two different copies of its address.
With pointer Vs Without pointer
1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function.
With pointers
...
int a = 10;
func(&a);
...
void func(int *x);
{
//do something with the value *x(10)
*x = 5;
}
Without pointers
...
int a = 10;
a = func(a);
...
int func(int x);
{
//do something with the value x(10)
x = 5;
return x;
}
2) Global or static variable has life time scope and local variable has scope only to a function. If we want to create a user defined scope variable means pointer is requried. That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function.
3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers.
struct data;
struct data
{
int no1, no2, ans;
void (*pfAdd)(struct data*);
void (*pfSub)(struct data*);
void (*pfMul)(struct data*);
void (*pfDiv)(struct data*);
};
void add(struct data* x)
{
x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...
4) Consider a structure data which size s is very big. If we want to send a variable of this structure to another function better to send as reference. Because this will reduce the activation record(in stack) size created for the new function.
With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func
...
struct data a;
func(&a);
...
Without Pointers - It will requires s bytes in activation record(in stack) of function func. Conside the s is sizeof(struct data) which is very big value.
...
struct data a;
func(a);
...
5) We can change a value of a constant variable with pointers.
...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...
in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value.
So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf));

const char passed to a function is not reflecting back

I want to change the contents of a constant-character-array(const array[64]).
Below is my code.
My Question is, why does the constant character array doesn't change(not reflected back), when passed to the function as constant character pointer(const char *append)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int function(char *d,const char *append)
{
append = d; //changing the location of append.
printf ("%s\n",append); //displays as sachintendulkar.
}
int main()
{
char *d = NULL;
const char append[]={'s','a','c','h','i','n'};
d = calloc(sizeof(char),sizeof(append));
strcpy(d,append);
strcat(d,"tendulkar"); //appending
function(d,append);
printf ("%s\n",append); //Its displays as sachin instead of sachintendulkar???
}
Function arguments are passed by value, when you assign a new value to the pointer append inside function(), nothing happens that is noted outside the function.
It's not very clear what you're trying to do ... The point of constant data is, of course, that you're not supposed to change it.
It is just a coincidence that the names of the parameters are the same as the variables in main. There is no connection between the names.
Your function works the same as if it was
int function(char *x, const char *y)
{
 y = x; //changing the location of y.
 printf ("%s\n", y); //displays as sachintendulkar.
}
You wouldn't expect that function to change the values inside main.

Resources