This is not my exact code, but it is like this in essence. I'm trying to create a stack variable in main()
int **x;
that I want to pass to a function foo(int **x, arg1, arg2, ...). On some condition, I'm supposed to dynamically allocate space for x in foo()
x = (int **) malloc(sizeof(int *) * num_elems);
I am also not allocating new space for each int * element, but assigning to it &y, where int y was created in foo().
I got this error when I tried freeing x in main(). I don't understand what it means, but I suspect it might be because I used &y?
EDIT: Also relevant: I got garbage values when I tried accessing the double-dereferenced elements of x.
You are not correctly declared in main function and not correctly defined in foo() function. You have to declare as
In main function
int *x ;
foo(&x);
In foo(int **x,....)
*x = malloc(sizeof(int) * num_elems);
Consider this,
void foo()
{
int y;
int *x = NULL;
x = &y;
}
In this case, y is stored in the stack. When foo returns, y will be unavailable (implementation dependant). If you absolutely need to do this, malloc y instead. If you do that, y will be stored on the heap instead.
Related
I have following code, and I want to change array passed trough multiple functions like this:
int main(void)
{
int *arr, n;
scanf("%d", &n);
arr = (int*)malloc(n*sizeof(int));
for (i = 0; i < n; i++)
//scanning into array
func1(arr, n);
}
Now I want each loop to change array and then use the changed arr in next loop etc
void func1(int *x, int h)
{
for (int i = 1; i < height; i++)
change(&x, h, i);
}
Here I need to change the original array to be same as gArr or have same values
void change(int **x, int h, int i) {
int *gArr = (int*)malloc(h*sizeof(int));
//doing some operations
//here I want to somehow change the original array to be gArr
//or to have the same values as gArr
*x = gArr;
}
I've tried multiple approaches and I somehow can't get the right result, thanks for help.
Your call graph is:
main(void)
func1(int *x)
change(int **x)
so if you pass a pointer variable from main, through func1 to change and then change the variable (i.e. the memory location pointed to), then you must also pass its address to func1, otherwise main can never observe the change:
main(void)
func1(int **x)
change(int **x)
...and don't forget to free the original array in change.
You need to distinguish between a pointer to an array, and the elements of that array. Let's first go through what you're doing right now:
int main(void)
{
int *arr, n;
scanf("%d", &n);
arr = (int*)malloc(n*sizeof(int));
// ...
func1(arr, n);
}
int *arr declares a pointer to an int in the scope of the function main().
At some pointer later you pass this pointer to the function func1. Now C is a pass by value language, that means that func1 gets the value of arr, and that value is the address of your dynamically allocated array. This allows your to manipulate the elements that arr points to, but not arr itself. So if inside func1 you have:
void func1(int *arr, int n) {
arr = dynamic_pointer_to_another_array();
}
only the arr inside of func1 is gonna change but not the one in main. Now you've partially figured that out, because your change() function takes a pointer to pointer instead, however in func1() you have:
change(&arr, h, i);
You might think the & here is passing the address of arr from main, but it's actually passing the address of arr from func1, because once again C is a pass by value language. Every time you pass a value to a function it gets copied to that function's scope, and any operations on the value won't be reflected in the caller.
The simple solution to this is to change func1 to take a int **arr instead of int *arr, that way you can do:
change(arr, h, 1);
and inside change you can then do:
*arr = new_array();
This would work because then you're passing the address of the pointer instead of the pointer itself, and through the address of the pointer you can change what the pointer points to.
Important Note
Your code has another huge problem. You're dynamically allocating an array and then trying to reassign the pointer to that array to another array. This is gonna certainly cause memory leaks and dangling pointers. Doing
int *arr = malloc(sizeof(int) * N);
arr = new_array();
is guaranteed to cause memory leaks, because you never use free on that pointer to deallocate the memory, and after you reassign it to another array, you lose all references to it. You have a couple of options of how to go about this. If you need to grow the size of arr then you use realloc instead of allocating a new array. That way you'll still have to only free once.
So the problem is your change of altering value inside the address doesn't take affect right, HOW COULD IT BE UPDATED, when you are dealing with a copy of the array you made in the main.
I've seen you have used int** type inside the parameter list of the function change(int**, int, int). And the reason to use this because the change can take effect on the passed array right!
In the same way, You should also use int** inside like this func1(int**) so that operation can reflect on the original one.
I somehow figured it out this way:
void func1(int *x, int h)
{
for (int i = 1; i < height; i++)
change(x, h, i);
}
void change(int *x, int h, int i) {
int *gArr = (int*)malloc(h*sizeof(int));
//doing some operations
memcpy(x, gArr, h*sizeof(int));
free(gArr);
}
memcpy did the job, but I'm not sure if its the right approach.
I am having trouble with this problem:
#include <stdio.h>
void change_number(int *x);
int main()
{
int x;
printf("Enter the number x: ")
scanf("%d", &x);
printf("In the main program: x = %d\n", x);
change_number(&x);
printf("In the main program: x = %d\n", x);
return 0;
}
void change_number(int *x)
{
x = *x+3;
printf("In the subroutine: x = %d\n", x);
}
Expected output:
Enter the number x: 555
In the main program: x = 555
In the subroutine: x = 558
In the main program: x = 558
Two notes:
I cannot modify main, or anything that comes before it. I can only modify the void change_number function, and the code inside it is my own code.
I cannot get the required output – my code only outputs x+3 in the subroutine, but doesn't change it in the main program.
How would I go about changing the value in the main routine? Please keep in mind that I am very new to C, and don't know many things yet (in fact, I just covered pointers yesterday).
The code
void change_number(int *x)
{
x = *x+3;
printf("In the subroutine: x = %d\n", x);
}
should read
void change_number(int *x)
{
*x = *x+3;
printf("In the subroutine: *x = %d\n", *x);
}
This will use the pointers as intended (you need to dereference them on the LHS as well)
I think an answer to the OP question needs a little bit explanation as C syntax may be confusing at times:
The function is declared as
void change_number(int *x)
The * means that the input parameter x is a pointer to a variable of type int. In other words x represents a location in memory.
Inside the function:
x is the address in memory of the int value
*x is the "content" of the memory address pointed by x
So, as other correctly pointed out, the function should be written as
void change_number(int *x)
{
*x = *x+3;
printf("In the subroutine: x = %d\n", *x);
}
Because as you act on *x you're acting on the content pointed by x
What is happening into main() ?
x is an int variable.
And you call:
change_number(&x);
The amplersand & means that you're not passing the value of x.
Instead you're passing a pointer to x, in other words the address in memory where the content of x is stored.
In other-other words x is passed by reference.
A final note: when writing a program in c (well, in any language, but expecially in c) the compiler warnings/errors and the debugger are your best friends.
Furthermore a good IDE will show you warnings as you type the code.
Anyway... the compiler should have warned you that
x = *x+3;
involves an implicit conversion from a int to int * (pointer to int) and most likely is a mistake.
You should use
*x = *x+3;
instead of
x = *x + 3;
What a function does with its parameters is, it makes a copy to work on and once the function's scope is ended, the copy is released which cannot change a value of a parameter passed to a function from outside.This is where pointers come in.
when passing a pointer to a function, think of it as a copy of the real address where in your case x is stored.
Thus in order to use x or change x, you have to use or change respectively *x(and it gets later dereferenced in the main program by &.
so like many others mentioned x = *x+3; should be *x = *x+3; and you'll get the desired results
Instead of printing in the change function you can also print in the main function by doing
*x=*x+3
A function returns a void double pointer containing a pointer to a float array, how can i access the output data?
void **pointer;
// function(void **ptr)
function(pointer);
This pointer points has to point to a float type pointer.
float *coords;
coords = (float*)malloc(3*500*sizeof(float)); //I know the amount of memory to be allocated
How can I read the data from this void double pointer? I'm pretty confused.
Your function prototype is not with respect to what you want to achieve. If you want your function to allocate memory and send its reference back to the main then your function will look like this (considering you want to pass double pointer) :
void function(void ***ptr)
{
float *coords;
coords = (float*)malloc(3*500*sizeof(float));
*ptr = (void **) &coords;
//do something
return;
}
main()
{
void **pointer;
function(&pointer);
/* Accessing first member of array allocated in function */
printf("%f", (*((float **)pointer))[0]);
}
If this is the objective, there is simpler way :
void function(void **p)
{
float *coords;
coords = (float*)malloc(3*500*sizeof(float));
*p = coords;
return;
}
main()
{
void *pointer;
function(&pointer);
printf("%f", ((float*)pointer)[0]);
}
Hope this helps.
Please check your code. What you are posting is nonsense - you have an uninitialised variable and pass it to a function. That's undefined behaviour and can crash or worse before the function even starts executing.
I think you are confused by what you call a "double pointer". There is no such thing as a "double pointer". A pointer points to something, it doesn't double-point. A pointer might point to an int (an int*), or to a struct T (struct T*) or to a float* (a float**). In the float** there are two *'s, but that doesn't make it a "double pointer". It is an ordinary pointer that happens to be pointing to something that is itself a pointer.
Pointers as function parameters are most often used so that the function can return more than one value. Say a function get_width_and_height returning to ints:
void get_width_and_height (int* width, int* height) {
*width = 10;
*height = 20;
}
int x, y;
get_width_and_height (&x, &y);
Now with that example in mind, how would you write a function that returns two int and one float* ?
I am going to have to make a few assumptions here as the question is unclear
I am going to assume that you call the function thus:
void **pointer;
function(pointer);
Then want to access the output, so do
flow *coord = (float *) *pointer;
Then you are home free
Hello i have this code and when it reaches the second printf there is an error compiler...i think it's about the pointer *y of the function
#include <stdlib.h>
#include<stdio.h>
int *x,*y;
void duplicate(int*x,int *y,int elem){
int j;
y=(int*)malloc(elem*sizeof(int));
for(j=0;j<elem;j++){
y[j]=x[j];
x[j]=x[j]+1;
}
}
int main(){
int j;
y=(int*)malloc(2*sizeof(int));
*y=10;*(y+1)=50;
duplicate(y,x,2);
printf("the poin y con y[0]=%d and y[1]=%d\n",y[0],y[1]);
printf("the poin y con x[0]=%d and x[1]=%d\n",x[0],x[1]);
return 0;
}
When you allocate memory for y (which is the global x) in function duplicate(), it doesn't update the global x because y is a local variable in duplicate().
You don't need to pass x from main() as it's a global variable. If you do need to pass then pass a pointer to pointer to update it:
duplicate(y,&x,2);
and update the function duplicate() to use *y:
*y=malloc(elem*sizeof(int));
and so on.
Suggestions:
Casting the return value of malloc is dangerous in C.
Don't write variable names as confusing as you did here. x is a global variable but you are passing it to a function but calling y there.
Use a standard signature for main() such as: int main(void).
Your problem is that you change the memory address of the pointer y within the duplicate.
When you pass a pointer to a function, a copy of that pointer is created as a local variable in the function. It still points at the same int, so if you dereference the pointer and change the value of the integer, that new value is retained when you return from the function. However, if you change the memory address that is pointed to, as with malloc, only the local copy of the pointer is changed, and the global variable y still points to some unallocated address which may contain garbage or cause a segmentation fault.
To fix this, you could pass a pointer to a pointer - i.e. int** y, or alternatively you could have duplicate return the new memory address:
int * duplicate(int*x,int *y,int elem){
int j;
y=(int*)malloc(elem*sizeof(int));
for(j=0;j<elem;j++){
y[j]=x[j];
x[j]=x[j]+1;
}
return y;
}
Then in main() call it as:
x = duplicate(y,x,2);
Of course, there is no actual reason to pass the target pointer to the duplicate function, so you can simplify it to this:
int * duplicate(int*x,int elem){
int j;
int *y;
y=(int*)malloc(elem*sizeof(int));
for(j=0;j<elem;j++){
y[j]=x[j];
/* I'm not sure why you have this line here, bug? */
x[j]=x[j]+1;
}
return y;
}
Then call it as:
x = duplicate(y,2);
Something I stumbled upon and made me wonder.
Why does this work?
void foo (int* a)
{
int x = 3;
*a = x;
}
int main()
{
int a;
foo(&a);
return 0;
}
But this causes a segmentation fault (both on Visual Studio 2008 and gcc)?
void foo (int* a)
{
int x = 3;
*a = x;
}
int main()
{
int* a;
foo(a);
return 0;
}
Is it something defined in the language or just an implementation issue?
When you declare
int* a;
You are declaring a pointer variable a but you are not making it point to anything. Then in the function, you do
*a = x;
Which dereferences the pointer and tries to assign what it points to the value of x. But since it doesn't point to anything, you get undefined behaviour, manifested in a segmentation fault.
You should do this:
int i; // the actual integer variable
int* a = &i; // a points to i
The difference between that and the first one is that int a; declares a real integer variable, then you take its address with &a and passes it to the function. The pointer a inside the function foo points to the variable a in main, and so dereferencing it and assigning to it is perfectly fine.
int a;
Assigns memory as soon as you declare it but this not the case with int *a;
int *a;
is pointer declaration (MEMORY not yet allocated for that).
int *a = (int*)malloc(sizeof(int)); // allocate memory