Passing char pointer in C - c

Okay so I am trying to pass a char pointer to another function. I can do this with an array of a char but cannot do with a char pointer. Problem is I don't know the size of it so I cannot declare anything about the size within the main() function.
#include <stdio.h>
void ptrch ( char * point) {
point = "asd";
}
int main() {
char * point;
ptrch(point);
printf("%s\n", point);
return 0;
}
This does not work however, these two works:
1)
#include <stdio.h>
int main() {
char * point;
point = "asd";
printf("%s\n", point);
return 0;
}
2)
#include <stdio.h>
#include <string.h>
void ptrch ( char * point) {
strcpy(point, "asd");
}
int main() {
char point[10];
ptrch(point);
printf("%s\n", point);
return 0;
}
So I am trying to understand the reason and a possible solution for my problem

This should work since pointer to the char pointer is passed. Therefore any changes to the pointer will be seen outside thereafter.
void ptrch ( char ** point) {
*point = "asd";
}
int main() {
char * point;
ptrch(&point);
printf("%s\n", point);
return 0;
}

void ptrch ( char * point) {
point = "asd";
}
Your pointer is passed by value, and this code copies, then overwrites the copy. So the original pointer is untouched.
P.S. Point to be noted that when you do point = "blah" you are creating a string literal, and any attempt to modify is Undefined behaviour, so it should really be const char *
To Fix - pass a pointer to a pointer as #Hassan TM does, or return the pointer as below.
const char *ptrch () {
return "asd";
}
...
const char* point = ptrch();

Here:
int main() {
char * point;
ptrch(point);
You're passing point by value. Then, ptrch sets its own local copy of point to point to "asd", leaving the point in main untouched.
A solution would be to pass a pointer to main's point:
void ptrch(char **pp) { *pp = "asd"; return; }

If you change the value of the pointer in a function, it will remain changed only in that one function call.
Don't mess your head with pointers and try:
void func(int i){
i=5;
}
int main(){
int i=0;
func(i);
printf("%d\n",i);
return 0;
}
The same with your pointer. You do not change the address it points to.
If you assign to a variable passed by value, the variable outside the function will remain unchanged.
You could pass it by a pointer (to pointer) and change it by dereferrencing it and it's the same with an int - in this case, it doesn't matter if the type is int or char * .

first declare funtion......like this
#include<stdio.h>
void function_call(char s)
next write main code.....
void main()
{
void (*pnt)(char); // pointer function declaration....
pnt=&function_call; // assign address of function
(*pnt)('b'); // call funtion....
}

Related

Why can't I malloc request memory and assign a value in a function using a string, but a string in a struct can?

why it wrong
`
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char* dest, const char* src)
{
dest = malloc(strlen(src) + 1);
strcpy(dest, src);
}
int main()
{
char* name0;
char* name1 = "Jam";
func(name0, name1);
puts(name0);
free(name0);
return 0;
}
but
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct st
{
char* name;
};
void func(struct st* st1, const struct st* st2);
int main(void)
{
struct st name0, name1;
name1.name = "Jam";
func(&name0, &name1);
puts(name0.name);
free(name0.name);
name0.name = NULL;
exit(0);
}
void changename(struct st* st1, const struct st* st2)
{
st1->name = malloc(strlen(st2->name) + 1);
if(st1->name == NULL)
exit(1);
strcpy(st1->name, st2->name);
}
`
is right
#I tried to use the first method to explain why the second method makes sense and why the second method solves the problem, but the first one reports an error and doesn't give me the answer I want.
#Why can't I malloc request memory and assign a value in a function using a string, but a string in a struct can?
Try passing the pointer to the character pointer by reference not by value.
void func(char** dest, const char* src)
{
*dest = malloc(strlen(src) + 1);
strcpy(*dest, src);
}
Other errors that might be present aside, the big difference between those two is an additional level of indirection.
Consider this struct
struct foo {
int * x;
};
And now this two functions:
void f1(int* a) { a = nullptr; }
void f2(foo* f) { f.x. = nullptr; f = nullptr;}
When f1 is called, modifying the local copy a has no effect on the pointer passed by the caller:
int i = 0;
int* ptr = &i;
f1(ptr); // a copy of ptr is made
assert( ptr == &i); // ptr still points to i
The same is true for the pointer passed to f2. Modifying f inside f2 has no effect on the pointer passed by the caller. Though, you can modify what f points to in f2, and that is visible to the caller.
foo fo;
int i = 0;
fo.x = &i;
foo* foptr = &fo;
f2(foptr); // a copy of foptr is made, it also points to fo
assert( fo.x == nullptr); // the function did modif fo
assert( foptr->x == nullptr);
assert( foptr == &fo ); // same as above, foptr still points to fo
In one case, you have func(name0, name1). In the other, you have func(&name0, &name1).
A function cannot change the value passed to it. When you pass name0, the function cannot change name0. It receives only a copy of its values. Similarly, when you pass &name0, the function cannot change the value of &name0. However, that value points to an object. The function can change the object it points to.
When you pass &name0, and the function executes st1->name =…, it changes the name inside the object that st1 points to, which is name0.
If you call the first function the same way as the second, func(&name0, &name1), then the function will be passed pointers to name0 and name1 instead of being passed their values. Then you need to change func to match:
void func(char **dest, const char **src)
{
*dest = malloc(strlen(*src) + 1);
strcpy(*dest, *src);
}
With these changes, the function operates on the things that its parameters dest and src point to instead of on the values in dest and src.
(It is not necessary to change the src parameter in the call and the function definition, since the source object does not need to be changed. I changed it only to match your second function.)

How to modify a heap pointer from a function [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 3 years ago.
How can I change a heap allocated global pointer from within a function? Here is what I am working with, (call to modify_p seg faults and I can't see much in the debugger):
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int *p, int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p(int *p) {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(p, 3);
modify_p(p);
//printf("%d\n", p[0]);
// should print 2
return 0;
}
Thanks
The issue is that you pass a copy of p to set_p. So the original p is never modified and never points to valid memory, and the copy is lost at the end of set_p, leaking the memory. Instead, pass a pointer to p (so a pointer to a pointer), like this:
void set_p(int **p, int sz) {
*p = malloc(sz * sizeof(int));
}
And call the function like this:
set_p(&p, 3);
Then you get the expected result.
One way would be to do this:
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p() {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(3);
modify_p();
printf("%d\n", p[0]);
// should print 2
return 0;
}
As p is declared outside of any function, you can write directly to it. When you do set_p(p, 3);, the set_p function will have it's local copy of the variable.
If you want to change what a pointer points to, you have to pass the address of the pointer (as shown by Blaze).

How to fill an array of structs in a function [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 4 years ago.
I'm trying to create an array of a structure in an external function "add", and print it's fields, but when I get back to the main function "arr" it is still NULL.
I'm confused because I've been creating arrays in external functions many times and it worked.. probably this time the dynamic memory allocation is messing the things up. Can I please get an advice on this matter?
Thanks!
typedef struct {
char* id;
char gender;
char *name;
}Member;
void add(Member arr[], int size);
void print(Member arr[], int *size);
int main()
{
char temp[100];
int size=0;
Member *arr = NULL;
Member *data = (Member*)malloc(sizeof(Member));
//scan fields
gets(temp);
data->id = (char*)malloc((strlen(temp) + 1) * sizeof(char));
strcpy(data->id, temp);
gets(temp);
data->gender = temp;
gets(temp);
data->name = (char*)malloc((strlen(temp) + 1) * sizeof(char));
strcpy(data->name, temp);
add(data, &arr, &size);
print(arr, &size);
return 0;
}
void add(Member *data, Member arr[], int *size)
{
arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
arr[*size] = *data;
}
void print(Member arr[], int *size)
{
for (int i = 0;i < *size;i++)
{
puts(arr->id);
puts(arr->gender);
puts(arr->name);
}
}
Imagine code like this:
#include <stdio.h>
void f(int i){
i++;
}
int main(){
int i = 3;
f(3);
printf("%d\n", i);
}
We all know that f() incremented its local copy of i, not the variable that was passed into f() to initially set that value. With that having been said, let's take another look at your add():
void add(Member *data, Member arr[], int *size)
{
arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
arr[*size] = *data;
}
When arr is passed into the function, it contains a memory address of the current arr, which starts as NULL. But just like when we change the local value of i in f() above, setting arr to a new value within add() only changes the local value; it does not change main()'s arr.
We also know that if we pass a function an address of data we want it to change, the function can then change the data at that address and the data at that address will reflect the change in the calling function:
#include <stdio.h>
void f(int * i){
*i = *i + 1;
}
int main(){
int i = 3;
f(&i);
printf("%d\n", i);
}
The same logic applies ( though it gets more confusing) when you want to change a pointer's value; send that pointer's address! Let's start with a very simple case:
#include <stdio.h>
#include <stdlib.h>
void f(int** i){
*i = (int*)malloc(sizeof(int));
**i = 99;
}
int main(){
int *i = NULL;
f(&i);
printf("%d\n", *i);
}
Here we create a pointer to an int in main, and initialize it to NULL. Then we send the address of that pointer (that is, the address we stored the NULL) to f(), which (like in your program) allocates some memory and puts the address of the newly allocated pointer _at the address of main's i. Now, the data stored at &i has changed, and dereferencing i from main() will dereference the newly allocated address.
In your code, just as in mine, you'll have to change the way you're passing arr to add() as well as how you interact with it - an exercise you'll get the most out of thinking through yourself. But in short, something like this should get you started:
pass add arr's address, not the address it stores.
Store new address of reallocated memory back to the same address, that is, &arr
make sure to update add() to dereference the pointer to a pointer twice to set the member at the address stored at the address &arr.

Pointer manipulation inside function

Let's say I have a pointer pointing to memory
0x10000000
I want to add to it so it traverses down memory, for example:
0x10000000 + 5 = 0x10000005
How would I do this inside a function? How would I pass in the address that the pointer points to, and inside the function add 5 to it, then after the function's complete, I can use that value?
You have two options:
The function can return the updated pointer.
char *f(char *ptr) {
ptr += 5;
return ptr;
}
The caller then does:
char *p = some_initialization;
p = f(p);
The function argument can be a pointer to a pointer, which it indirects through:
void f(char **ptr_ptr) {
*ptr += 5;
}
The caller then does:
char *p = some_initialization;
f(&p);
Basically, like what everyone else as said you have to pass the pointer by reference(that is a pointer to a pointer aka double pointer) to the function.
#include<stdio.h>
void IncrementAddress(void **addr)
{
int offset=5;//give what ever value you want
*addr = *addr + offset;
printf("%d\n",*addr);
}
int main()
{
char x;// or any other data type like int x or float x etc.
void *ptr=NULL;
ptr = &x;
printf("%d\n",ptr);
IncrementAddress(&ptr);
printf("%d\n",ptr);
return 0;
}

C newbie malloc question

Why doesn't this print 5?
void writeValue(int* value) {
value = malloc(sizeof(int));
*value = 5;
}
int main(int argc, char * argv) {
int* value = NULL;
writeValue(value);
printf("value = %d\n", *value); // error trying to access 0x00000000
}
and how can I modify this so it would work while still using a pointer as an argument to writeValue?
Your pointer (int *value) is a value. If you want to keep the above behavior, you need a pointer to a pointer.
void writeValue(int** value) {
*value = malloc(sizeof(int));
**value = 5;
}
int main(int argc, char * argv) {
int *value = NULL;
writeValue(&value); // Address of the pointer value, creates int**
printf("value = %d\n", *value); // prints 5
}
There are 2 bugs, from what I see:
1) If you want to change the value of your pointer you need to pass a pointer to the pointer to your function int **value.
2) If you want to print the value of the pointer in your main, you need to defreference it, *value.
call malloc before calling writevalue, not inside it (thus you'll get the added benefit to be able to free it).
Your program doesn't print 5, but also has a memory leak by losing address of allocated bloc.
The reason as also explained by others is that the parameter int * value is a copy of int * valuein main. You can think of it as a local variable of the function. You can only access to the place it is pointing to. When you modify value in the function the other value in main is not changed.
void writeValue(int* value) {
*value = 5;
}
int main(int argc, char * argv) {
int* value = NULL;
value = malloc(sizeof(int));
writeValue(value);
printf("value = %d\n", *value);
free(value);
}

Resources