Reputation: 140
I am trying to assign the return value of a function to variable, the problem is that this return value is an array, I understand that it will return a pointer, but as you can see below I just couldn't do the proper assignment, I've looked at many questions and don't seem to get what I need. So here is my function:
int randn(int n, int l){
int r[n];
int i;
for ( i=0; i<n; i++){
r[i]=rand() % l;
r[i]++;
}
return *r;
}
I believe the function is ok, but when I try to do this int *o; o=randn(n,l);
I get this warning:
warning: assignment makes pointer from integer without a cast [enabled by default]
And when I execute it, I get a segmentation fault. This may be a dumb question, but I have been trying to solve this for a long time now. I would appreciate some kind help. Thank you in advance.
Upvotes: 1
Views: 134
Reputation: 404
First, If you define an Array in C, say int r[n] in your case, the r is actually a const pointer in most of the context implicitly converted into a const pointer of first element. Although pointer and array is different pointer arithmetic and array indexing [that] are equivalent in C. The operator * get the value at pointer. So *r is equivalent to r[0] in this case. So you must return r not *r if you want to get the full array not the first element.
C compiler shows the warning because it checks that type of left hand side (int pointer) is not equal to type of right hand side (int).
int *o;
o = randn(n,l);
Second, a local variable exists in the memory as long as it is in the scope. C uses Lexical Scoping (Static Scoping). As as soon as you are out of the function after return the memory of r will be freed. In C you will get Segmentation fault generally when you try to access a memory location not reserved by the Program.
So you need to allocate memory by using malloc. return type of malloc is (void *). So cast it into (int *).
int *r = (int *) malloc(n * sizeof(int));
malloc will not assign memory if it get no free memory at all. So its a good practice to check whether r is not NULL.
Change the return type of the function into (int *) from int. Remember C compiler only does this type checking by function declaration. It is not dependent on the actual returned value.
Memory allocated by malloc should be freed once the use is over by free(p) to avoid memory leak.
Upvotes: -1
Reputation: 320777
In C language it is not possible to return an array from a function. The proper way to go about it in C is to actually pass the recipient array from the calling code and then simply fill it inside the function
void randn(int n, int r[n], int l)
{
for (int i = 0; i < n; ++i)
{
r[i] = rand() % l;
++r[i];
}
}
...
int o[n];
randn(n, o, l);
The approach with malloc
-ing the array inside the function, while formally correct, is seriously flawed since it forces the code to work with dynamic memory. In many/most cases there's simply no reason to involve dynamic memory.
With this approach you have full freedom to put your array in any kind of memory you see fit, since the responsibility of providing that memory is imposed on the calling code.
Upvotes: 0
Reputation: 121427
That's not the correct way to a pointer from a function. Also r
is local variable whose lifetime is limited to the function. Allocate memory using malloc
and return it instead:
int* randn(int n, int l){
int *r=malloc(n * sizeof *r);
if(!r) { */ error */}
int i;
for ( i=0; i<n; i++){
r[i]=rand() % l;
r[i]++;
}
return r;
}
Notice that I changed the signature as well to return a pointer (int*
). Caller is responsible for free()
ing the memory.
Upvotes: 2
Reputation: 9002
r[0]
value.r
array disappears as soon as your function returns, and the pointer becomes invalid.Upvotes: 0