0

I need to read inputs from a csv and put it into a dynamically allocated array Ay.

int* Ay = malloc(nz * sizeof(int));

The number of inputs from the csv will vary in each case. Later I pass Ay to another function where I need to calculate its length. I have used the following methods but it doesn't give me the right result.

int Aylen = sizeof(Ay) / sizeof(Ay[0]);

or

int Aylen= 1[&Ay] - Ay;

or

int Aylen=*(&Ay+1)-Ay;

Please suggest a way to find the length. Thank you.

dbush
  • 205,898
  • 23
  • 218
  • 273
S2022
  • 35
  • 3
  • 2
    Keep track of the length in a variable. – Shawn May 28 '22 at 17:59
  • `nz` already has the length. Just pass it as an extra argument to the functions. – Craig Estey May 28 '22 at 18:01
  • You allocated it, so you already know the size. A pointer is just a pointer, you need to pass the size as well as the pointer. – Clifford May 28 '22 at 18:03
  • There's a list of frequently asked questions in the [tag info for C](https://stackoverflow.com/tags/c/info). You should take the time to read all of them, but at least the six that apply to arrays. – user3386109 May 28 '22 at 18:15

2 Answers2

0

There is no portable way to determine the size of a dynamically allocated buffer. You need to keep track of that yourself.

This means you have to pass both Ay and nz to any function that accesses Ay.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

It is not possible in C language.

You need to keep trach of the size.

Example:

typedef struct
{
    size_t length;
    int data[];
}data_t;


data_t *add_element(data_t *arr, int element)
{
    size_t newsize = arr ? arr -> length + 1 : 0;
    arr = realloc(arrr, newsize * sizeof(arr -> data[0]) + sizeof(*arr));
    
    if(arr)
    {
        arr -> length = newsize;
        arr -> data[newsize - 1] = element;
    }
    return arr;
}

0___________
  • 60,014
  • 4
  • 34
  • 74
  • 1
    I'd do: `int *data` and add `size_t capacity` – Craig Estey May 28 '22 at 18:11
  • @CraigEstey why double reference? – 0___________ May 28 '22 at 18:46
  • What you did _is_ valid [and may be the best solution for a memory constrained MCU]. But, with `int *data` the struct mimics a C++ `vector` impl. After doing (e.g.): `data_t *arr = calloc(1,sizeof(*arr));` to create it, all functions [that resize or _don't_ resize] can be: `void func(data_t *arr,...)` Otherwise, we'd need: `data_t *arrgrow(data_t *arr,...)` or `void arrgrow(data_t **arr,...)` and `void arrnogrow(data_t *arr,...)`. The caller needs to keep track of more things. – Craig Estey May 28 '22 at 19:09
  • @CraigEstey no we do not need any double pointers. Avoiding side effects is the best way. – 0___________ May 28 '22 at 21:20