2

Hey the idea of the code is to scan an array of floats and then create another function that prints that array from the back to the start. For some reason it prints zeros only. Why does it still refer to the part where I set the array to 0? -- float* arr = { 0 };

void ScansFloat(float* arr, int size);
void PrintsFloat(float* arr, int size);

int main()
{
    float* arr = { 0 };
    ScansFloat(arr, 5);
    PrintsFloat(arr, 5);
}

void ScansFloat(float* arr, int size)
{
    int save;
    arr = (int*)malloc(size * sizeof(int));
    for (int i = 0; i < size; i++)
    {
        printf("Enter number in position %d\n", i+1);
        scanf("%f", arr + i);
    }
}

void PrintsFloat(float* arr, int size)
{
    for (int i = size; i >= 0; i--)
    {
        printf("Number %d is %f\n", size - i +1, arr + i);
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
adirk1
  • 219
  • 1
  • 11
  • Remember: In C parameters are passed by value. This means whatever you store in your local copy of `arr` inside `ScansFloat` will not be visible outside of that function. – Gerhardh Nov 09 '21 at 18:54
  • May we see the implementation for `koletSifronim`? – Chris Nov 09 '21 at 18:54
  • 1
    You should enable your compiler warnings. `"%f"` expects a value of type `double` while you pass `arr + i` which is a pointer. – Gerhardh Nov 09 '21 at 18:54
  • `ScansFloat()` should return a pointer to the array. The pointer returned by `malloc()` is local to the function... – arfneto Nov 09 '21 at 18:55

1 Answers1

3

Pass the address of the pointer.

The below code does not change the calling code's pointer.

void ScansFloat(float* arr, int size) {
    ...
    // Here the prior value of `arr` is lost.
    arr = (int*)malloc(size * sizeof(int));  // Wrong type
    for (int i = 0; i < size; i++) {
      ...
      scanf("%f", arr + i);
    }
}

Instead pass the address of the pointer. Also size to the referenced object, not the type. It avoids coding mistakes.

void ScansFloatAlternate(float** arr, int size) {  // **, not *
    ...
    // *arr = (int*)malloc(size * sizeof(int));
    *arr = malloc(sizeof **arr * size);
    if (*arr == 0) Handle_OutOfMemeory();
    for (int i = 0; i < size; i++) {
      ...
      scanf("%f", (*arr) + i);
    }
}

float* arr = 0; // or NULL
ScansFloatAlternate(&arr, 5);

Note: other general improvements possible.


Perhaps a different approach: return the allocated pointer. Various improvements applied.

// Return NULL on error
// Use size_t for sizing
float* ScansFloat(size_t n) {
  float *arr = malloc(sizeof *arr * n);
  if (arr) {
    for (size_t i = 0; i < n; i++) {
      printf("Enter number in position %zu\n", i + 1);
      if (scanf("%f", &arr[i]) != 1) {
        // Invalid input, so consume to the end of the line.
        int ch;
        while ((ch = getchar()) != '\n' && ch != EOF) {
          continue;
        }
        free(arr);
        return NULL;
      }
    }
  }
  return arr;
}

Usage

// float* arr = { 0 };
// ScansFloat(arr, 5);
size_t n = 5;
float* arr = ScansFloat(n);
if (arr == NULL) Fail();
...
free(arr); // free when done
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Or have `ScansFloat()` return the pointer to the allocated array, and drop the relevant input parameter. – Jonathan Leffler Nov 09 '21 at 18:59
  • `*arr = malloc(sizeof **arr * size);` better `float *x = malloc(sizeof **arr * size);` then in the function `scanf("%f", x + i);` and when everything is OK `*arr = x`. But generally IMO it is mych better to not introduce side effects in such trivial functions and return reference to the allocated block. – 0___________ Nov 09 '21 at 19:16
  • @0___________ Agree that is better in a final product, yet I wanted to go from where OP was to close to best, without changing the style too much, changing what should be changed and leaving the less preferable _as is_ to focus on the main issue: passing a pointer to the address. – chux - Reinstate Monica Nov 09 '21 at 19:21
  • I can’t upvote a second time, sadly. – Jonathan Leffler Nov 09 '21 at 19:53
  • 1
    @chux-ReinstateMonica indeed. :) – Gerhardh Nov 09 '21 at 22:35