I'm trying to build a program that modifies the element of an array through a pointer to a pointer. I loaded it into the debugger and I see that the value of my pointer changes, but for some reason that doesn't affect the element in the array. Is my pointer syntax wrong? Am I reassigning my pointer somewhere else?
#include <stdio.h>
#include <stdlib.h>
#define SIZE 6
/*
*
*/
void change (char **x);
int main() {
char arra[] = "Back";
char *c = arra;
change(&c);
int i;
printf("%c", arra[0]);
}
void change (char **x) {
*x = "H";
}
*x = "H";
should be
**x = 'H';
You are trying to modify the first character and character has to be within single quotes.
There is no need of pointer to pointer here. You can just pass the array which decays to a pointer when passed in the function parameterks as shown by #haccks
No need to use pointer to pointer in this case. Just use pointer to char.
void change (char *x);
and call it as
change(c);
with the function body
void change (char *x) {
*x = 'H';
}
Related
I want to pass a pointer as a size element of an array
example:
void hello(int array1[how can i refer pointer "ptr" here][2])
{
// i want to access the array used in the main() here
printf("hi");
}
int main()
{
int c=5;
int *ptr=&c;
a[*ptr][2];
a[0][1]=0;
a[0][2]=4;
}
I apologize for not being clear with my question here , i want to access the array used in the main() function in my hello() function.
You will have to use the value pointed to by the pointer:
a[*ptr][2];
ptr is the address pointed to by the pointer not the value stored there. You use the dereference operator * to get the value.
Of course, ptr is not of type int, it's of type int * (integer pointer). An array subscript must be of type int.
Maybe what you want is a[*ptr][2].
You need to deference the pointer by using *ptr so
int c = 5;
int *ptr = &c;
a[*ptr][2];
otherwise you are not using the value of ptr you are using its address in memory which returns an error.
Use the dereference operator *:
a[*ptr][2];
The expression *ptr tells the compiler to use the value pointed to by ptr.
As for your updated question, that's not possible. But it's not needed either, as it's passed as a pointer anyway.
When declaring a function, this:
void foo(int a[5][5])
is the same as this:
void foo(int a[][2])
And also the same as this:
void foo(int (*a)[2])
It has pretty much been answered already, you can't call an adress in the array a[0x3950f2][2]
Always use the pointer* to get the position in the array a[*ptr][2] to get the expected value - in this case: a[*ptr][2] == a[5][2]. You may read this.
Edit to your updated question: You can't to this. You can use the pointer when you call the function or when using the variable in the function.
Your second edit:
void hello(int **array1)
{
// i want to access the array used in the main() here
printf ("hi");
a[0][0] = 24;
}
int main()
{
int c = 5;
int *ptr = &c;
int **a;
a[*ptr][2];
a[0][1] = 0;
a[0][2] = 4;
hello (a);
return 0;
}
I have a question regarding passing arrays in c to a function.
When I run this program it gives me a segmentation fault
int main()
{
char **ptr= NULL;
test(ptr);
printf("%s", ptr[0]);
return 0;
}
void test(char **ptr)
{
ptr = (char **) malloc(sizeof(char *));
ptr[0] = (char *) malloc(sizeof(char)*5);
strcpy(ptr[0], "abc");
return;
}
but this worked just fine
int main()
{
char **ptr= NULL;
test(&ptr);
printf("%s", ptr[0]);
return 0;
}
void test(char ***ptr)
{
*ptr = (char **) malloc(sizeof(char *));
*ptr[0] = (char *) malloc(sizeof(char)*5);
strcpy(*ptr[0], "abc");
return;
}
Could someone explain why?
You're passing the parameter ptr by value; the formal parameter ptr in test is a different object from the actual parameter ptr in main, so changing the value of test::ptr is not reflected in main::ptr.
Thus, you need to pass a pointer to ptr into test, and test needs to dereference that pointer to write to the correct object.
For any type T, if you want to modify the value of the function argument, you need to do the following:
void foo( T *param )
{
*param = ...;
}
void bar( )
{
T obj;
foo( &obj );
}
In this particular instance, T is char **.
In C, when you pass an array to a function, the array "decays" to a pointer. The function receives a pointer to the first element of the array. It does not receive the array itself. Any changes made to the pointer assignment in the called function are not reflected in the calling function.
In your first example, test() receives the array of strings, and inside the function, it changes what that pointer points to. So the local copy of ptr, which was NULL, gets allocated memory inside the function, as does ptr[0]. However, those changes are local to test(). They are not reflected in the calling function. When test() finishes executing and returns, the value of ptr in the calling function is still NULL. And you have a memory leak because there is no way to access the memory that was allocated in test().
In order for the changes to be reflected in the calling function, you have to pass a pointer to the array of strings: hence the &ptr in the call and the three-level pointer in the definition of test(). Another, simpler approach would be:
int main()
{
char **ptr= NULL;
ptr = test();
printf("%s", ptr[0]);
return 0;
}
char** test(void)
{
char **ptr = (char **) malloc(sizeof(char *));
ptr[0] = (char *) malloc(sizeof(char) * 5);
strcpy(ptr[0], "abc");
return ptr;
}
One clarification: I said "Any changes made to the pointer assignment in the called function are not reflected in the calling function." This is not the same as saying "Any changes to array elements are not reflected in the calling function." Consider this:
int main (void) {
int array [] = { 0, 1, 2, 3, 4 };
test1 (array);
printf ("%d\n", *array);
test2 (array);
printf ("%d\n", *array);
return 0;
}
void test1 (int* array) {
int new_array[] = { 3, 4, 5, 6, 7 };
array = new_array;
return;
}
void test2 (int* array) {
array [0] = 5; // or *array = 5
array [1] = 6;
array [2] = 7;
array [3] = 8;
array [4] = 9;
return;
}
Output:
0
5
Here in test1() the change is to where the array pointer itself is pointing, which won't be reflected in the caller. So in the calling function, *test is still 0. In test2(), the changes are to the array elements, which are reflected in the caller. Hence the difference in output: *test is now 5. All this uses static rather than dynamic memory allocation, but the principle is the same.
It's because you expect your function not to return a value, but to modify a variable you have already created in another scope.
You expect, from your function, to pass ptr and end up with the following structure:
ptr -> b -> []
where b is a pointer to the array [].
In the first example you are not modifying the outer ptr inside the function, but a copy of it. In that case, to get the desired structure you'd need your function to return a char** so that you could return the allocated pointer. And you wouldn't need to pass the original ptr.
In the second example, on the other hand, you are passing a pointer to the outer ptr, so the function will be modifying the same memory space that the outer ptr uses.
I hope this can help a little.
Consider below code for understandling
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void test(char **ptr);
int main()
{
char *ptr= NULL;
test(&ptr);
printf("%s\n", ptr);
return 0;
}
void test(char **ptr)
{
*ptr = malloc(sizeof(char *));
strcpy(*ptr, "abc");
return;
}
Whatever doing in function definition has to be reflect in main function. So if you want to make changes in ptr variable you have to pass the address of the ptr variable.
ptr is single pointer(char ptr) variable, we need to pass address of the pointer(&ptr) variable.
In function definition we are receiving address of pointer variable, so argument has to be the type of double pointer.
This concept is similar to call by reference.
Similar things happening in your code also.
You need to pass address of double pointer to make changes in pointer variable.
Address of double pointer has to taken by triple pointer in function definition.
To expand on the answer from #rcrmn.
It is a good program design to have data get passed "up" the calling structure. In this case main() needs to free the storage it received from test.
Notice that this code avoids all of the double pointers in the original question and still meets the requirements. This is the essence of good programming, write clear, simple, code that gets the job done.
#include <stdio.h>
char *test();
int main()
{
char *ptr = test();
printf("%s", ptr);
free(ptr);
return 0;
}
char *test()
{
char *ptr = (char *) malloc(sizeof(char) * 5);
strncpy(ptr, "abc", 3);
return ptr;
}
I'm trying to understand the mistake in the following code. The code is supposed to switch between two arrays.
What I saw is that it switches only the first 4 bytes. Is the following correct?
Passing &num1 or num1 is the same (both pass the address of the first element in the array).
The (char**) casting is wrong. That's because when you pass and array you pass the address it's laid in. So you actually pass here a void*.
How can I actually switch between these two arrays only by pointers? Is thatpossible?
I know it is possible if from the beginning I had defined char **num1 and char **num2. But I want it to stay with the array notation!
#include <stdio.h>
void fastSwap (char **i, char **d)
{
char *t = *d;
*d = *i;
*i = t;
}
int main ()
{
char num1[] = "hello";
char num2[] = "class";
fastSwap ((char**)&num1,(char**)&num2);
printf ("%s\n",num1);
printf ("%s\n",num2);
return 0;
}
Passing &num1 or num1 is the same (both pass the address of the first element in the array). Am I correct?
No. The first one is a pointer to the array itself (of type char (*)[6]), whereas in the second case, you have a pointer to the first element (of type char *; an array decays into a pointer to its first element when passed to a function).
The (char*) casting is wrong
Indeed, you are casting a char (*)[6] to a char **.
So you actualy pass here a void (Am i correct?).
No. Non sequitur. I don't see how the void type is relevant here. You have pointers, arrays, and eventually pointers to arrays.
Arrays are not pointers. Your code is trying to swap arrays, which does not make sense, since assignment to arrays is not permitted. What you probably want is
I. either get pointers to the first character of each string, and then swap the pointers themselves, like this:
void swap_pointers(const char **a, const char **b)
{
const char *tmp = *b;
*b = *a;
*a = tmp;
}
const char *p1 = "hello";
const char *p2 = "world";
swap_pointers(&p1, &p2);
II. Or use actual arrays, and you swap their contents:
void swap_contents(char *a, char *b, size_t n)
{
for (size_t i = 0; i < n; i++) {
char tmp = a[i];
a[i] = b[i];
b[i] = tmp;
}
}
char a1[] = "hello";
char a2[] = "world";
swap_contents(a1, a2, strlen(a1));
Also, you may want to read this.
1. Passing &num1 or num1 is the same (both pass the address of the first element in the array)
Not true, &num1 gives you a pointer to a pointer that points to the entire character string "hello" (char*[6]) while num1 is just a pointer to the character block "hello" (char[6]).
2. The (char*) casting is wrong. That's because When you pass and array you pass the address it's laid in. So you actualy pass here a void (Am i correct?).
It is still not a void, it's just a pointer to a character pointer. If it were void, then it would be perfectly valid to do something like void** myVoid = &num1. This will cause a syntax error unless you explicitly typecast your char** to a void** before you assign it.
The problem is your explicit type casting &num1 as a char** which is not correct, it is a char*[6]. But of course, you can't declare a variable as a char*[6] so it can't be used in this way. To fix it you need to declare your num1 and num2 as:
char* num1 = "hello";
char* num2 = "class";
instead and keep everything else the same. In fact, with this change there is no need to typecast your &num1 as a char** because it already is that.
Please find the code snippet as shown below:
#include <stdio.h>
int My_func(int **);
int main()
{
int a =5;
int *p = &a;
My_Func(&p);
printf("The val of *p is %d\n,*p);
}
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
*p = Ptr;
}
How does by using a double pointer as a argument in my_Func function and making change of value reflects the same in the main function but if we use a single pointer in My_Func does not change the value in main?Please do explain me with examples if possible
Advanced thanks
Maddy
int **p is a pointer to a pointer-to-int. My_Func(int **p) works by changing the value of integer that the pointer-to-int points to i.e. int a.
Without changing the implementation, the function will not work with a pointer-to-int parameter int *p as there is a second level of indirection. In addition, you're setting the value to a local variable that is created on the stack. When the function is completed the memory used for the variable will be reclaimed, therefore making the value of a invalid.
void My_Func(int **p)
{
int val = 100; // Local variable.
int *Ptr = &val; // This isn't needed.
*p = Ptr;
} // val dissapears.
Remove the second level of indirection and copy val by value instead of pointing to it:
#include <stdio.h>
void My_Func(int *p)
{
int val = 100;
*p = val;
}
int main(void)
{
int a = 5;
My_Func(&a);
printf("The val of a is %d\n", a);
return 0;
}
In short, in C when you pass something as a parameter, a copy will be passed to the function. Changing the copy doesn't affect the original value.
However, if the value is a pointer, what it points to can be changed. In this case, if you want to affect the pointer, you need to pass a pointer to it down to the function.
Use it in the function declaration:
void func(int *p)
{
int val =100;
int *temp=&val;
p=temp;
}
p starts pointing to another address i.e. address of val. So it will print the value 100.
Important note: Try it in your downloaded compiler (always in case of pointers) not in the online compiler. The online compiler doesn´t keep track of lost addresses in stack.
You are assigning the address of local variable, which will soon disappear when My_Func returns. You can use following in your code. However you can do the same thing just by using single pointer, double pointer is not required in this example.
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
**p = *Ptr;
}
In this program I have swapped the first 2 names
#include<stdio.h>
void swap(char **,char **);
main()
{
char *name[4]={"amol", "robin", "shanu" };
swap(&name[0],&name[2]);
printf("%s %s",name[0],name[2]);
}
void swap(char **x,char **y)
{
char *temp;
temp=*x;
*x=*y;
*y=temp;
}
This programs runs perfectly but when I use the function swap(char *,char *) it does not swap the address why? why I have to use pointer to pointer?
I assume you understand that to swap integers you would have function like swap(int *, int *)
Similarly, When you want to swap strings which is char *. You would need function like swap(char **, char **).
In such cases, you take their pointers and swap their content (otherwise values will not be swapped once function returns). For integer content, pointer is int * and in case of strings content is char * pointer to it is char **.
Pointers (like all values) are passed by value.
If you use swap(char * a,char * b) and write a = tmp; this changes only the local variable a and not the original variable in the caller.
This simpler example also doesn't work as intended for the same reason:
void change(int x) {
x = 0; // Only changes the local variable.
}
int main(void) {
int x = 0;
change(x); // This does not have any effect.
printf("%d", x); // 0 is printed
return 0;
}
http://ideone.com/u7Prp
char *name[4] is holding address of 3 string literals. If we want to swap, we have to pass the reference of the array where exactly the string literal's address is stored. That means we have to pass name+0 and name+2 or &name[0] and &name[2] to the swap function.
And also if you want to swap. you have to receive the address as char ** and then we have to change the address of the string literals in the array.
If you receive it as char * and if you tries to change like temp = x; x = y; y = temp, that will be local change to the function swap. It will not reflect on the array name.
Sounds like this is what you are looking for:
#include<stdio.h>
void swap(char *,char *);
main()
{
char name[4][10]={"amol", "robin", "shanu" };
swap(name[0],name[2]);
printf("%s %s",name[0],name[2]);
}
void swap(char *x,char *y)
{
char *temp;
temp=x;
x=y;
y=temp;
}
The main difference is the declaration of name. In your version you declare an array of pointers so you have to dereference the entries as *name[0]. In the second version it declares an array of 'char arrays' or strings and each entry holds a string, not a pointer, so you can dereference the entries as name[0]. You will see the difference clearly if you use gdb and step through the code while using the print command.