Reputation: 25
I have written a function to allocate memory for an array and store the array length in a pointer so I can use both in my main function. Everything seems to work fine until I try to loop through the array printing the values.
When I use the array size pointer to terminate the print loop it shows strange behaviour. Could you please show me where I am going wrong?
Thanks in advance :)
#include <stdio.h>
#include <stdlib.h>
void func (int** arr, int** len){
int length = 5;
*len=&length;
*arr = malloc(sizeof(int)*(**len));
for (int i=0; i<(**len); ++i){
(*arr)[i]=i*10;
}
}
int main(){
int* len = NULL;
int* arr = NULL;
func(&arr, &len);
for (int i=0; i<5; ++i){
printf("%d\n", arr[i]);
} //works
/*
for (int i=0; i<*len; ++i){
printf("%d\n", arr[i]);
} //doesnt work
*/
free(arr);
return 0;
}
Upvotes: 1
Views: 73
Reputation: 7345
for (int i=0; i<*len; ++i){
printf("%d\n", arr[i]);
}
The above code doesn't work because the contents of len
are indeterminate.
Using *
with an indeterminate or NULL
pointer has undefined behaviour.*
In the function func
, lenght
is a local variable, which is destroyed once the function returns.
The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime.²
For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way.³
As the lenght
is known at compile time and never changes, there's no need to pass a pointer to pointer to an int
. Just pass an int
for the allocation.
[1], [2], [3] — C11, 6.2.4 Storage Duration of Objects.
Upvotes: 1
Reputation: 118097
int length = 5;
*len=&length;
You here assign *len
to point at a local variable (length
). The local variable length
will go out of scope when the function returns and dereferencing the pointer after that will have undefined behavior.
You'd get the correct behavior if you instead allocate the memory for the int
in main
and provide a pointer to that memory to func
.
#include <stdio.h>
#include <stdlib.h>
void func(int** arr, int* len) { // int* instead
int length = 5;
*len = length;
*arr = malloc(length * sizeof **arr);
for (int i = 0; i < length; ++i) {
(*arr)[i] = i * 10;
}
}
int main() {
int len; // automatic storage
int* arr = NULL;
func(&arr, &len);
for (int i = 0; i < len; ++i) {
printf("%d\n", arr[i]);
} // now works
free(arr);
}
Upvotes: 1
Reputation: 121
You should have worked correctly with the pointer. You passed a pointer to a pointer to a function and you're trying to write a value to the pointer.
int a = 0;
fun(&a);
{
*a = 42;
}
#include <stdio.h>
#include <stdlib.h>
void func (int** arr, int* len){
int length = 5;
*len=length;
*arr = malloc(sizeof(int)*(*len));
for (int i=0; i<(*len); ++i)
{
(*arr)[i]=i*10;
}
}
int main(){
int len = 0;
int* arr = NULL;
func(&arr, &len);
for (int i=0; i<5; ++i){
printf("%d\n", arr[i]);
} //works
for (int i=0; i<len; ++i){
printf("%d\n", arr[i]);
} //doesnt work
free(arr);
return 0;
}
Upvotes: 0