I am not sure if I use realloc and malloc in true purpose

Hi,
I wanted to make a function that can create an array of sine waves.
But when I call the function more than one time, it overwrites on the array which I used before. Why is this happening?

Code:

float* array1;
float* array2;

void func(uint16_t frequency, float* _array){
  uint16_t s = 488/frequency;
  realloc(_array,s*2);
  for(uint16_t i;i<s*2;i++){
    *(_array+i) = (sin(i*PI/s+3*PI/2)+1)*255/2;
  }
}

void setup() {
  Serial.begin(9600);
  array1 = (float*)malloc(0);
  array2 = (float*)malloc(0);
}

void loop() { 
  func(4,array1);
  func(8,array2);
  for(uint16_t i;i<244;i++){
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(array1[i]);
  }
  for(uint16_t i;i<122;i++){
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(array2[i]);
  }
  while(1);
}

I would also like to know since I've never used malloc() in my years of programming the Arduino.

Huh. I'd never seen malloc(0) before. but apparently it should work?

This, however is wrong:

  realloc(_array, s * 2);

realloc() returns a pointer to the bigger (or smaller) chunk of memory; you can't count on that being at the same place. From the man page:

The realloc() function tries to change the size of the allocation pointed to by ptr
to size, and returns ptr. If there is not enough room to enlarge the memory alloca-
tion pointed to by ptr, realloc() creates a new allocation, copies as much of the
old data pointed to by ptr as will fit to the new allocation, frees the old alloca-
tion, and returns a pointer to the allocated memory.

Allocating memory at run time is a very risky business in the small memory of an Arduino. Much better to allocate space for your arrays at compile time.

...R

_array is local to func() any changes made to it are not saved.

void func(uint16_t frequency, float** OutArray){
  float* _array = *OutArray;
  uint16_t s = 488/frequency;
  realloc(_array,s*2);
  for(uint16_t i;i<s*2;i++){
    *(_array+i) = (sin(i*PI/s+3*PI/2)+1)*255/2;
  }

  *OutArray = _array;
}

void setup()
{
   ...
   func(100, &array1);
}

You are committing THE cardinal sin of malloc()/alloc()/realloc()/sbrk() use - you never NOT check to see if a NULL pointer is returned.

And I would NOT count on malloc(0) returning a valid allocation block. I would instead initialize the pointer to NULL, and instead of doing a realloc, simply do the malloc there instead. If you MUST use realloc(), first check if the pointer is NULL, and, if so, then do a malloc() at that time. Blindly using what any of those functions return WILL blow up your program at some point.

Regards,
Ray L.

RayLivingston:
You are committing THE cardinal sin of malloc()/alloc()/realloc()/sbrk() use - you never NOT check to see if a NULL pointer is returned.

And I would NOT count on malloc(0) returning a valid allocation block. I would instead initialize the pointer to NULL, and instead of doing a realloc, simply do the malloc there instead. If you MUST use realloc(), first check if the pointer is NULL, and, if so, then do a malloc() at that time. Blindly using what any of those functions return WILL blow up your program at some point.

Regards,
Ray L.

malloc(0) and realloc(NULL) are both safe. Their behaviors are well defined in the manual.
The place OP needs to NULL check is where he accesses it.