Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Say I have something like:
function2(int *hello) {
//something
}
function1(int *hello) {
function2(&hello);
}
void main() {
int hello = 0;
function1(&hello);
}
How do I make it so that function2 can change the original value declared in main?
Change this code:
function1(int *hello) {
function2(&hello);
}
to:
function1(int *hello) {
function2(hello); // <-- no "&" in this call!
}
Then you can do this:
function2(int *hello) {
*hello = 123; // <-- dereference pointer hello
}
You are making a mistake in the function1 where your pass the address of the pointer to your int hello in the main function. you pass the pointer forwart to the function2 and the dereference it in there.
function2(int *hello) {
*hello = 123 ;
}
function1(int *hello) {
function2(hello); //pass the pointer on to function2
}
int main( void ) {
int hello = 0;
function1(&hello);
return 0 ;
}
You are also incorrectly declaring your main function. It should be declared as int main() with a return statement.
As mvp reply it is correct answer but i am here just explaining something, which will help you to understand, why your code is not working.
First let me explain operator you used
1] Ampersand Operator (&)
This operator helps you to get reference/address of variable
As soon as we declare a variable, the amount of memory needed is assigned for it at a specific location in memory, As we generally do not actively decide the exact location of the variable within the operating system during run time but some time we need to know address of our variable like here You want to know the address of variable to assign it's address to pointer The address that locates a variable withing memory is what we call a reference to that variable Which we can get using Reference variable.
Dereference Operator (*)
As we know that pointer is the variable which will store that address of the another variale, using pointer we can directly access the value stored in the variable which it points.To do this we simply have to precede the pointer's identifier with an asterisk (*), which acts as deference operator and that can be literally translated to value pointed by
Now back to your code
function2(int *hello) { // Here you create function that accept address of variable (You will get address of hello pointer 101 NOT 100 of variable assign in your MAIN)
//something
}
function1(int *hello) {// Here you create function that accept address of variable (Here it will get address of hello which is 100)
function2(&hello); // Here you again pass address of your pointer hello (Which may be 101) [BAD]
}
main {
int hello = 0; // Let say it's address is 100
function1(&hello); // Here you pass address of your variable(which is 100) [GOOD]
}
Solution is as suggested
function2(int *hello) {
//Change your value here
*hello = 123;
}
function1(int *hello) {
function2(hello); // It will pass 100 (address of your variable hello assign in MAIN
}
main {
int hello = 0;
function1(&hello);
}
The "&" operator means "address of", so your function 1 is trying to call function2 with the address of "hello" rather than the address hello contains.
Responding to a different question I said this:
Pointers are variables which store a number, like any other, but because you tell the compiler it is a pointer, the compiler allows you to use that value as an address of things in memory and the language provides "dereferencing" as a way of saying "the value AT the address this variable describes".
Imagine you're going to the airport to catch a flight. You grab a post-it note and write down your flight number, and you take a second post-it with you for your gate.
The first post it is a "flight*" pointer and your second is a "gate*" but right now the gate* pointer is empty.
When you get to the airport, you look up your flight on the board and jot down the gate number. "3A". Now your gate* post-it is valid.
But the post-it itself is NOT your gate, it just points to it: you still have to "dereference" the post-it note to get to your flight - that is, walk across the airport to gate 3A :)
When you called function1 you took the address of the variable in main. All you need to do is forward it to function2. What your code was trying to do was make a note of which post-it not the gate number was on, rather than just looking at the post-it note.
Solution
#include <stdio.h>
void function1(int*); // so the compiler knows what the function looks like.
void function2(int*);
int main() {
int varInMain = 0; // lets call it something distinct
printf("varInMain starts with %d, it's location in memory is %p.\n",
varInMain, &varInMain);
function1(&varInMain);
printf("varInMain is %d after calling function1.\n", varInMain);
return 0;
}
void function1(int* func1ptr) {
printf("function1: func1ptr points to memory location %p, which contains %d.\n",
func1ptr, *func1ptr);
*func1ptr = 1010;
function2(func1ptr);
}
void function2(int* func2ptr) {
printf("function2: func2ptr points to memory location %p, which contains %d.\n",
func2ptr, *func2ptr);
*func2ptr = 123;
}
You can see a live demo of this code on ideone.com here.
Output looks like this:
varInMain starts with 0, it's location in memory is 0xbfef2fdc.
function1: func1ptr points to memory location 0xbfef2fdc, which contains 0.
function2: func2ptr points to memory location 0xbfef2fdc, which contains 1010.
varInMain is 123 after calling function1.
Related
I was trying to understand the concept of passing by reference. When I do this,
#include<stdio.h>
int recent (int *a)
{
*a = 20;
return 0;
}
int main()
{
int bee;
bee=5;
int *val = &bee;
printf("Value is %d\n", *val);
recent(val);
printf("Now Value is %d\n", *val);
return 0;
}
Basically I am making the pointer val point to the memory location of bee, and then when I pass it to recent function, and change the value, that change gets reflected in the calling function, so the value changes to 20. But when I do this,
#include<stdio.h>
int check = 20;
int recent (int *a)
{
a = ✓
return 0;
}
int main()
{
int bee;
bee=5;
int *val = NULL;
recent(val);
printf("Now Value is %d\n", *val);
return 0;
}
I get segmentation fault.
Is it because I didn't initialize the pointer to point to any location, and then I passed the value to recent function, and even though I made it point to a memory location (check variable), the calling function didnt catch that because I was passing by value?
Is this completely true or I misinterpreted something and got lucky with the answer?
Your problem is that you are printing the output of dereferencing the pointer val in the main function. The value of the pointer val in the main function is NULL. Thus the program is trying to print the thing at memory location 0, which is inaccessible to your program and results in a segmentation fault.
First you create the val pointer and assign it the value NULL.
int *val = NULL;
Then you call recent, passing it the pointer val, which still holds NULL.
recent(val);
Finally you print *val. val still holds NULL, and the * operator tells the compiler to "dereference" val, meaning to use the value of the thing that val is pointing to.
printf("Now Value is %d\n", *val);
In response to the question of whether your description is correct, the answer is sort of, but your description is imprecise. You made the function's copy of the pointer point to something. When you implement a pass-by-reference function in C using pointers, you are still passing the pointers themselves by value: a copy of the pointer is made, pushed onto the stack, and sent to the function. If you update the value of the pointer in the called function, the value of the pointer in the calling function will not be changed.
The reason has to do with your function recent(). When you pass in "a" you are passing in an int* (i.e. int pointer) which is an address to a location in memory. However, "a" as you have it, is local to this function (the pointer is pass by value).
Thus when you set "a = &check", you are only changing the local pointer value. As soon as recent() returns, "a" goes out of scope. In this context, you are never changing what "a" actually points to.
Thus, you segfault because val is still null, and you are trying to dereference a NULL pointer.
val is still a null pointer after leaving the function. The pointer itself is (as you correctly guessed) only passed by value, not by reference. Inside the function you are only modifying the pointer (which only lives insides the function), not the pointer target.
Besides that, please be careful with passing around memory locations to automatic stack variables. At least coming from a C++ background, it's considered bad style. Since you don't explicitly control the life cycle of a stack variable yourself (as you would do with malloc/free), you can easily shoot yourself in the foot by accidentally dereferencing pointers which have already been cleaned from the stack.
Is it because I didn't initialize the pointer to point to any location,
Code well initialized with int *val = NULL;, yet NULL is not a valid location. It isn't the NULL is a location or not. It is the NULL is the null pointer constant. As a null pointer, it "is guaranteed to compare unequal to a pointer to any object or function."
... and even though I made it point to a memory location (check variable), the calling function didn't catch that because I was passing by value?
Yes. With a = ✓, only the local a was affected, not the val in which a was copied from as the actual augment val was passed by value (copied) to the formal parameter a.
Is this completely true ...
IMO: Yes
... I misinterpreted something and got lucky with the answer?
It appears no misinterpretation. Lucky - hard to rate.
Here is what is going on in your code:
#include<stdio.h>
int check = 20;
int recent (int *a)
{
a = ✓
return 0;
}
int main()
{
// memory is allocated to hold an integer
int bee;
// the number 5 is written into that memory space
bee = 5;
// memory is allocated to hold a memory address
// the value of null (which is a invalid address) is written into it
int *val = NULL;
// more memory is allocated to hold a memory address (int* a)
// the address in val (which is null) is written into it
// the new memory address (a) now points to the address of check
recent(val);
// val is still NULL
// BOOOM!
printf("Now Value is %d\n", *val);
return 0;
}
Long story short, you are correct! :)
It's basically what all have answered. It's because you are passing the address pointed by pointer a using Pass By Value method. That is your sending in a copy of the address. If you want the second code to work you need to change the code to the following,
#include<stdio.h>
int check = 20;
int recent(int **a)
{
*a = ✓
return 0;
}
int main()
{
int bee;
bee = 5;
int *val = NULL;
recent(&val);
printf("Now Value is %d\n", *val);
return 0;
}
That is you have to Pass the address pointed by a by using C version of "Pass By Reference".
I am having difficulty passing a char array to a function:
This is code is found inside a function, which calls another function createbitshape:
char ans[8];
char bitshp[8];
...
fgets(ans, 10, stdin);
createbitshape(random_num, bitshp);
printf("bitshp outside: %p\n", &bitshp);
Here is createbitshape:
void createbitshape(int n, char bitshp[]){
int i, count;
count = 0;
i = 1<<(sizeof(n) * 2 - 1);
for ( ; i > 0; i >>=1 )
{
if (n & i) /* check if any of the bits of n is not 0 .*/
bitshp[count] = '1';
else
bitshp[count] = '0';
count++;
}
bitshp[8] = '\0';
printf("bitshp inside: %p\n", &bitshp);
The prototype is:
void createbitshape(int, char[]);
When I run the code, I see two different addresses of bitshp:
bitshp inside: 0x7fff854d8b80
bitshp outside: 0x7fff854d8b70
How come ? Does createbitshape allocates another memory room ? How do I change this code such that createbitshape writes the content to bitshp defined in the calling function?
(p.s. I know similar questions have been already asked, but I simply don't get how to translate the answers there to my case...)
Your confusion is because the assumption is incorrect, there is no pass-by-reference in C, only pass-by-value.
When arrays are passed as function argument, they are automatically converted to a pointer that points to their first element. It looks like pass-by-reference as you can modify what the pointer points, but it's not, it's still pass-by-value, the value of the pointer itself.
That means the function argument bitshp is a new pointer, it's supposed to have a different address than the bitshp outside the function. But they do share the same value.
Yu Hao answer is great, I'm glad you accepted it.
I'd like to complement it with a brief explanation on why the addresses differ inside and outside. Its a combination of two things:
Array variables decay to pointers when they are passed as function arguments:
static size_t my_sizeof(char array[32]) {
return sizeof(array);
/* Always returns either 4 or 8 depending on your architecture */
}
When you use the address-of operator on an array, it will return the same address:
char array[8];
printf("%p %p\n", array, &array);
/* Will output the same value twice */
While learning pointers I tried pointer declarations/dereferenciations.
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int *call() {
int a = 3;
return &a;
}
int main() {
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
return 0;
}
So "obviously" the "a" is a local variable.
But my problem is,
when I'm reading out the address of "a", it's always the same address.
Why is that like this?
PS: I'm running a prime-number-calculator in the background to fill up as much memory as possible and I put in the "Sleep" to make the program wait, but still the address of "a" is always the same.
a is located on the stack of the current thread : every time the function call() is run, it "allocates" 4 bytes on the stack to stock a, return the address and then "frees" the space it uses on stack (it is not actually allocating/freeing anything, just offsetting the stack pointer).
So if you call it several times in a row, the state of the stack on input of the function will be exactly the same, so the actual address of a on the stack the same every time (please note that this address is invalid as soon as you exit the function).
You should do something like
int * call2(){
int a = 0;
int *b = call();
printf("%d",a);
return b;
}
and then
int *a = call();
int *b = call2();
You will see a and b will be different (the printf is there to make sure the compiler does not optimise anything away)
Since the stack is local to the current thread (not influenced by other processes/threads), your prime number calculator and Sleep are to no use at all.
"call" is to return a pointer to a variable? The problem here is that "a" is not statically allocated, but is on the stack. You can return its address at the moment (which may or may not be the same address, depending on whether "call" is invoked at the same depth each time), but there's no guarantee of what that address is pointing to once you return from "call". You put a 3 in it during the call, and that may be overwritten by something else by the time you get around to looking at the contents of that address.
I thought I understood the basics of pointers, but after checking out some documentation on some sqlite3 methods I got thrown, so now I am unsure if my understanding is correct.
Here is a call to an sqlite3 method:
char* dataFilePath = "foobar.sqlite";
if (sqlite3_open(dataFilePath, &database) != SQLITE_OK) {...}
And here is the function header declaration:
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
Why is it that &database suddenly becomes a pointer to a pointer?
Another method call to close the database connection is:
sqlite3_close(database);
With the following at the function header:
int sqlite3_close(sqlite3 *);
Why is this just a pointer, when I pass in a pointer? Would this not be a pointer to a pointer?
From all examples I have seen it always seemed the inverse of the functions above, ie.
// function
void foo(someDataType *bar) { ... }
// function call
foo(&bar);
Thanks for the help.
Most likely, sqlite3_open is allocating memory for the database handle. For this reason the function needs a pointer to a pointer to the database handle (sqlite3) so that it can modify the pointer to the database handle. For example:
typedef struct { /*...*/ } sqlite3;
int sqlite3_open(const char *filename, sqlite3 **ppDb) {
/* ... */
// Allocate memory for the database handle.
*ppDb = (sqlite3 *)malloc(sizeof(sqlite3));
/* ... */
return 0;
}
However, sqlite3_close only needs a single pointer to free the memory:
int sqlite3_close(sqlite3 *pDb) {
/* ... Cleanup stuff ... */
free(pDb);
return 0;
}
I think the short explanation for what you're asking is that using "&" essentially means "a pointer to this"
int value = 0;
int *pointer = &value;
int **doublePointer = &pointer;
A pointer is the address of a variable.
Assuming that database is declared as sqlite3* database;, &database is the address of (or, a pointer to) the database pointer.
sqlite3_open takes a pointer to a pointer so that it can set the value that the pointer points to. It makes a sqlite value, and changes your pointer to point to it. sqlite3_close doesn't change what the pointer points to, so all it needs is the pointer itself.
As usual, the C FAQ List contains relevant information. See I have a function which accepts, and is supposed to initialize, a pointer: and Does C even have "pass by reference"?.
i don't know what you want to do with sqlite function. But using pointers makes you to keep changes in functions.
When you pass a variable to a function, the variable will be duplicated.
for example
int var1=0;
in *ptr1=&var1;
func(var1, ptr1);
the value of var1=5
the adress of var1 = 0xff2200 (something like that)
the value of ptr1 = 0xff2200 (the adress of var1)
the adress of ptr1 = 0xff0022 (something different)
Lets write a function which uses these two var as arg
void func1(int x, int *p){
x+=5;
(*p)-=5;
}
after u use this function;
func(var1, ptr1);
var1 will not equal to 0!!! İt will be -5
Because;
in function func1
the value of x = 0 (the value of var1)
the adress of x = 0xaabbcc (something different then var1!!! this is why x+=5 is not effective on var1. It happens in another part of memory! When u return, this memory will be free again. And you'll lose your changes...)
the adress of p = 0xcccccc (something different too)
the value of p = 0xff2200 (the value of ptr1 and the adress of var1! This operation will be done in the var1's adress so you will not lose your changes)
İf we have to keep our changes of variables -in functions-, we have to use pointers for those var.
İf our variable keep an adress, it means; it is a pointer. And if we want to keep changes of pointer -in functions- then we have to use pointer to pointer.
This is my first message and i hope this will be helpfull...
And "pass by reference" means "pass by pointer" other languages don't use pointers. so you have to pass by reference sometimes. But in C, pointers will do its job...
I'm new to C, and am confused by results I'm getting when referencing a member of a struct via a pointer. See the following code for an example. What's happening when I reference tst->number the first time? What fundamental thing am I missing here?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int number;
} Test;
Test* Test_New(Test t,int number) {
t.number = number;
return &t;
}
int main(int argc, char** argv) {
Test test;
Test *tst = Test_New(test,10);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
}
The output is:
Test.number = 10
Test.number = 4206602
Test.number = 4206602
When you pass test into your Test_New function, you are passing it by value and so a local copy is made on the stack for the function scope of your Test_New function. Since you return the address of the variable, once the function returns the stack is useless but you've returned a pointer to a struct on the old stack! So you can see that your first call returns the correct value since nothing has overwritten your stack value but the subsequent calls (which all use the stack) overwrite your value and give you erroneous results.
To do this correctly rewrite your Test_New function to take a pointer and pass the pointer to the struct into the function.
Test* Test_New(Test * t,int number) {
t->number = number;
return t;
}
int main(int argc, char ** argv) {
Test test;
Test * tst = Test_New(&test,10);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
printf("Test.number = %d\n",tst->number);
}
Independent of struct, it is always incorrect to return the address of a local variable. It is usually also incorrect to put the address of a local variable into a global variable or to store it in an object allocated on the heap with malloc. Generally if you need to return a pointer to an object, you'll need either to get someone else to provide the pointer for you, or else you'll need to allocate space with malloc, which will return a pointer. In that case, part of the API for your function must specify who is responsible for calling free when the object is no longer needed.
You are returning the address of t as declared in the method Test_New, not the address of test that you passed into the method. That is, test is being passed by value and you should instead pass a pointer to it.
So, here is what happens when you call Test_New. A new Test struct named t is created and t.number is set to be equal to the value of test.number (which you had not initialized). Then you set t.number equal to the parameter number that you passed to the method, and then you return the address of t. But t is a local variable and goes out of scope as soon as the method ends. Thus, you are returning a pointer to data that no longer exists and that is why you are ending up with garbage.
Change the declaration of Test_New to
Test* Test_New(Test* t,int number) {
t->number = number;
return t;
}
and call it via
Test *tst = Test_New(&test,10);
and all will go as you are expecting.
Just to extend BlodBath's answer, think about what happens in memory when you do this.
As you enter your main routine, a new automatic Test struct is created -- on the stack, since it's auto. So your stack looks something like
| return address for main | will be used at bottom
| argc | copied onto stack from environment
| argv address | copied onto stack from environment
-> | test.number | created by definition Test test;
with -> indicating the stack pointer to the last used element of the stack.
Now you call Test_new(), and it updates the stack like this:
| return address for main | will be used at bottom
| argc | copied onto stack from environment
| argv address | copied onto stack from environment
| test.number | created by definition Test test;
| return addr for Test_new| used to return at bottom
| copy of test.number | copied into the stack because C ALWAYS uses call by value
-> | 10 | copied onto stack
When you return &t, which address are you getting? Answer: the address of the data ON THE STACK. BUT THEN you return, the stack pointer is decremented. When you call printf, those words on the stack are re-used, but your address is still poiting to them. It happens that what the number in that location in the stack, interpreted as an address, points to has the value 4206602, but that's pure chance; in fact, it was kind of bad luck, as good luck would have been something that caused a segmentation fault, letting you know something was actually broken.
The problem is that you are not passing a reference into Test_New, you are passing a value. Then, you're returning the memory location of the local variable. Consider this code which demonstrates your problem:
#include <stdio.h>
typedef struct {
} Test;
void print_pass_by_value_memory(Test t) {
printf("%p\n", &t);
}
int main(int argc, char** argv) {
Test test;
printf("%p\n", &test);
print_pass_by_value_memory(test);
return 0;
}
The output of this program on my machine is:
0xbfffe970
0xbfffe950
Test t declared in Test_New() is a local variable. You are trying to return the address of a local variable. As the local variable gets destroyed once the function exists, the memory will be freed meaning, the compiler is free to put some other value in the location where your local variable was kept.
In your program when you are trying to access the value the second time, the memory location might have got assigned to a different variable or process. Hence you are getting the wrong output.
A better option for you will be to pass the structure from main() by reference rather than by value.
You've passed the contents of test by value to Test_New. IOW a new copy of a Test structure has been allocated on the stack when you called Test_New. It is the address of this Test that you return from the function.
When you use tst->number the first time the value of 10 is retrieved because although that stack has be unwound no other use of that memory has been made. However as soon as that first printf has been called the stack memory is reused for whatever it needs, but tst is still pointing to that memory. Hence subsquent uses of tst->number retrieve whatever printf left there in that memory.
Use Test &t in the function signature instead.
You could do something like this to make it a little easier:
typedef struct test {
int number;
} test_t;
test_t * Test_New(int num)
{
struct test *ptr;
ptr = (void *) malloc(sizeof(struct test));
if (! ptr) {
printf("Out of memory!\n");
return (void *) NULL;
}
ptr->number = num;
return ptr;
}
void cleanup(test_t *ptr)
{
if (ptr)
free(ptr);
}
....
int main(void)
{
test_t *test, *test1, *test2;
test = Test_New(10);
test1 = Test_New(20);
test2 = Test_new(30);
printf(
"Test (number) = %d\n"
"Test1 (number) = %d\n"
"Test2 (number) = %d\n",
test->number, test1->number, test2->number);
....
cleanup(test1);
cleanup(test2);
cleanup(test3);
return 0;
}
... As you can see, its easy to allocate room for several completely different instances of test_t, for instance if you need to save the existing state of one so you can revert later .. or for whatever reason.
Unless, of course there is some reason why you must keep it local .. but I really can't think of one.