I am struggling to understand exactly what is happening when you return a new object from a function in go.
I have this
func createPointerToInt() *int {
i := new(int)
fmt.Println(&i);
return i;
}
func main() {
i := createPointerToInt();
fmt.Println(&i);
}
The values printed returned are
0x1040a128
0x1040a120
I would expect these two values to be the same. I do not understand why there is an 8 byte difference.
In what I see as the equivalent C code:
int* createPointerToInt() {
int* i = new int;
printf("%#08x\n", i);
return i;
}
int main() {
int* r = createPointerToInt();
printf("%#08x\n", r);
return 0;
}
The address returned is the same:
0x8218008
0x8218008
Am I missing something blindingly obvious here? Any clarification would be greatly appreciated!
You are printing the address of the pointer here fmt.Println(&i);. Try this:
func main() {
i := createPointerToInt();
fmt.Println(i); //--> Remove the ampersand
}
i is the pointer returned from createPointerToInt - while &i is the address of the pointer you are trying to print. Note in your C sample you are printing it correctly:
printf("%#08x\n", r);
^No ampersand here
Change &i to i. You are printing address of i while you should print the value of i.
func createPointerToInt() *int {
i := new(int)
fmt.Println(i);
return i;
}
func main() {
i := createPointerToInt();
fmt.Println(i);
}
But how come in your original code the addresses of the two pointers (not memory addresses the pointers are pointing too) are different?
func main() {
i := createPointerToInt();
fmt.Println(&i);
}
Is equivalent to:
func main() {
var i *int // declare variable i
i = createPointerToInt(); // assign value of
// a different i that was
// declared and initialized
// inside the function
fmt.Println(&i);
}
Edit:
To print the address of a struct you need to use:
fmt.Printf("%p\n", &your_struct)
golang.org/pkg/fmt/
For example:
goplayground
Related
Background: using cgo to call C functions from Golang.
I want to use a C function which has this signature: int f(int *count, char ***strs).
It will modify the data of count and strs, which is the reason why it uses pointer to them.
The value of count is the length of strs; strs is an array of string; the return value is simply an (boolean) indicator which states whether there is an error or not.
In golang, I can successfully pass and modify count by using C.f((*C.int)(&count)); pass []string by using []*C.char. Sample code is like this:
/*
#include <stdio.h>
int f(int *c, char **str) {
int i;
printf("%d\n", *c);
for (i = 0; i < *c; i++) {
printf("%s\n", str[i]);
}
*c = (*c) + 1;
return 1;
}
*/
import "C"
func go_f(strs []string) int {
count := len(strs)
c_count := C.int(count)
c_strs := make([]*C.char, count)
for index, value := range strs {
c_strs[index] = C.CString(value)
defer C.free(unsafe.Pointer(c_strs[index]))
}
err := C.f(&c_argc, (**C.char)(&c_argv[0]))
return int(err)
}
As you can see, the C function is currently int f(int *c, char **str), but what I'd like is int f(int *c, char ***str).
This is to say: what I actually want is to enable the modification to the string array (e.g. resize) in C and turn it back to a Go string slice so I can still use it in Go.
How to do this? I've searched and experimented for a while but with no luck.
A Go slice is both allocated in Go, and a different data structure than a C array, so you can't pass it to a C function (cgo will also prevent you from doing this because a slice contains a Go pointer)
You need to allocate the array in C in order to manipulate the array in C. Just like with C.CString, you will also need to track where to free the outer array, especially if the C function may possibly allocate a new array.
cArray := C.malloc(C.size_t(c_count) * C.size_t(unsafe.Sizeof(uintptr(0))))
// convert the C array to a Go Array so we can index it
a := (*[1<<30 - 1]*C.char)(cArray)
for index, value := range strs {
a[index] = C.CString(value)
}
err := C.f(&c_count, (***C.char)(unsafe.Pointer(&cArray)))
I know that If a function has no argument & only return type (say int), then I can change my int variable by assigning the function to my variable as below,
main()
{
int var_name;
var_name = func();
printf("My variable value is updated as : %d", a);
}
func()
{ return 100; }
Also I know that If I have my function's return type as void, with no arguments, then I can only print the value inside the function itself and cannot return anything in turn.
But, my doubt is, is there anything else that I can do to update my var_name by calling a function with no arguments & no return type ?
ie., void func(void); by using something like pointer concepts ??
I could not able to find the exact answer for the same by my searches among so many websites.. I will be very grateful if someone can help me out finding whether I can do it by this way or not,.
Thanks,.
It is possible to modify a local variable in main, from a function with no arguments and no return value, if there's a global pointer to it:
#include <stdio.h>
int *p;
void func() {
*p = 6;
}
int main() {
int a = 5;
p = &a;
func();
printf("a = %d\n", a); // prints: a = 6
return 0;
}
There's no good way to do that. If you want the function to modify a local variable, you should probably change the function so it either returns a value that you can assign to the variable, or takes the variable's address as an argument.
But if you don't mind writing some ugly code, you can define a global (file-scope) pointer variable, assign the local variable's address to the global pointer, and then use that to modify the variable inside the function.
An example:
#include <stdio.h>
int *global_pointer;
void func(void) {
*global_pointer = 42;
}
int main(void) {
int local_variable = 0;
global_pointer = &local_variable;
func();
printf("local_variable = %d\n", local_variable);
}
It's very easy to shoot yourself in the foot his way. For example, if you refer to the pointer after the calling function has terminated (and the local variable no longer exists), you'll have undefined behavior.
This technique can actually be useful if you need to make a quick temporary change in a body of code in which you can't make major interface changes. Just don't do it in code that will be maintained by anyone else -- and wash your hands afterward.
You can have global variable
int var_name;
void func();
int main()
{
func();
printf("%d\n",var_name);
}
void func()
{
var_name = 20;
}
But if your variable is local to main() then this can't be done.
There are two ways to modify the value of var_name.
Make changes in the calling function and return the value.( which you have already shown)
Pass the address of the var_name to the function and have pointer as arguement in the func(int *p) and modify the value inside the func()
Thats it!! No other way this can be done.
I'm calling a function which returns a 3D array. The problem is that if I declare the array inside the function it returns a dangling pointer as the execution of the program goes out of the scope of the variable. But when I declare the array outside the function, it gives Error:'array' was not declared in this scope. How should I declare the array? It returns integer type.
int arr[x][y][z];
int func(list of parameters)
{
//code
return arr;
}
int main()
{
int arr2[x][y][z];
arr2 = func(list of parameters);
return 0;
}
You try to return an integer value with a name arr, but you did not define int arr in the function scope.
C does not allow to return array by value. You need to pass a pointer to an array to the function in order to let it to modify array.
Something like:
void func(int*** array, <list of parameters>)
{
//code
array[1][2][4] = 10;
}
int main()
{
int arr2[x][y][z];
func(arr2, <list of parameters>);
return 0;
}
few problems in your code:
First, func function should return an int*** pointer. it is defined as returning int which is not the type you actually return.
Second, why retuning the global arr array from func? it simply modifies the global array.
int arr[x][y][z];
int func(list of parameters)
{
//code
return arr;
}
Third, why declaring arr2 to hold the result - simply reference the global array you've defined.
Fourth, defining int arr[x][y][z]; globally is not supported - the compiler would not know how to create this buffer - you should declare it with actual size to the array (e.g., int arr[10][10][10];
Either pass the array as a parameter in the function if you are declaring it outside the function or if you are declaring it inside the function then to deal with a dangling pointer
is for example -
char*func()
{
char str[10];
strcpy(str,"Hello!");
return(str);
}
//returned pointer points to str which has gone out of scope.
or you might be using memory that is being freed for example
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!
I know this question has been asked before but cannot find it in the same manner as I will describe it here:
Its all about returning an one-dimensional array in c-language. In java its very easy:
double[] myFunction() {
double[] v = new double[10];
return v;
}
I know that the implementation in c is not the same. But as an array element can be considered as a pointer to the first element in that array I thought one could do the following implementation:
double (*myFunction()) {
double v[10];
return v;
}
This compiles fine in gcc but when I make a call of the function I get a compilation error.
SO my Question - how does one return a one-dimensional vector in c-language?
Thanks
sample code
#include <stdio.h>
#include <stdlib.h>
double *myFunction1(){
return malloc(10*sizeof(double));
}
double (*myFunction2())[10]{
double (*p)[10];
p = malloc(sizeof(double[10]));
return p;
}
typedef struct d10 {
double vec[10];
} D10;
D10 myFunction3(){//Make little sense
D10 v = {{0}};
v.vec[9]=1.25;
return v;
}
int main(){
double *v1 = myFunction1();
double (*v2)[10] = myFunction2();
D10 v3= myFunction3();
//do something
printf("%lf\n", v3.vec[9]);
v1[0] = 3.14;
(*v2)[0] = 3.14 * 2;
free(v1);
free(v2);
return 0;
}
Corrected:
You can't pass an array and you can't return an array you only pass an address to it or return a pointer to it first element:
double *someFunction()
{
double *output;
p = (double *)malloc(size*sizeof(double)); // size should be defined
//... do some process with the content pointed to by output
return output; // return the address pointed to by output
}
Or pass a pointer to it first element and do some process on the content pointed to.
void someFunction(double *output, int size)
{
//... do some process with the content pointed to by output
}
For one, declaring v in the function makes the array live only in that function. Once the function returns, that array is popped off the stack, and is likely to be modified after successive function calls.
The proper C solution is to use malloc to allocate an amount of space that you can use as an array, and return the pointer to that array.
double * myFunc(){
double * v = malloc(10*size of(double));
return v;
}
In Java, it was safe to return an array because the garbage collector could detect that the array was still in use, after it was popped off the stack.
how does one return a one-dimensional vector in c-language?
Technically speaking, one doesn't. C functions cannot return array types.
The main problem you are running into is that, in the C code, v only exists for the lifetime of the function; once the function exits, v no longer exists, so any pointer you return will not be valid.
For this to work, you'll have to do something similar to what the Java code is doing; you'll need to allocate the memory for the array from the heap (i.e., allocate it dynamically):
double *myfunction()
{
double *v = malloc( sizeof *v * 10 );
return v;
}
Note that C does not clean up after you, so you'll have to explicitly free that memory when you're done with it, such as:
int main( void )
{
double *arr = myfunction();
/**
* do stuff with arr
*/
free( arr );
return 0;
}
A friend told me there is a way to check with printf without modifying the original void function.
But I can't see how you can do it.
#include<stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d",test());
}
I kept getting
error: invalid use of void expression
Is there a way to do it?
I see from your edit that you want to do this without modifying the function. You can employ the comma operator to make the function call in a printf:
#include <stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d\n", (test(), 0));
// or even this, to be more explicit:
printf("%s\n", (test(), "test() was called."));
}
The comma operator evaluates the first operand - in this case your function call - and discards the result, then evaluates the second operand and the result is the result of the entire expression.
An example would be to pass memory pointer into the void function and fill it with data you need to see if your void function worked.
void
test_funtion(bool *answer)
{
answer = false;
// do stuff
if(error happens)
return;
answer = true;
return;
}
I don't see how you would use printf to let the program know.
Only way you would use printf for visual logging for yourself, but not the machine.