Home > Net >  Allocating and accessing array inside C function
Allocating and accessing array inside C function

Time:01-14

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;
}

CodePudding user response:

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);
}

CodePudding user response:

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.

  • If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.


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,33) and retains its last-stored value throughout its lifetime.
  • Identifiers only have visibility inside their scope, starting at their declarations.
  • Unless they are VLA OR temporary objects, automatic variables have a lifetime corresponding to the execution of their block of definition.

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.

CodePudding user response:

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;
}
  • Related