Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Realloc + memcpy 2D float array results in segmentation fault

I made a structure (SomeMisc) which has a float array, so I can fill it with some values, and then try to memcpy its float array to a different struct’s float array, and print out the result to see if it worked.

The other structure (ArrayPairs) is supposed to hold two arrays of arrays. So that low[i] belongs to high[i] and vice versa when I want to make some changes on "a couple".

So I make 2 SomeMisc objects, fill their arrays with numbers, and then try to make a function where I expand the low-array and high-array of the ArrayPairs object with realloc firstly, then I try to malloc space to the new rows, and then finally memcpy content from the 2 SomeMisc member arrays given as arguments to the function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But it keeps resulting in segmentation faults and/or undefined behavior, and I can’t figure out why.

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <stdlib.h>

typedef struct some{
  int32_t len;
  float* arr;
} SomeMisc;

typedef struct arrPrs{
  int32_t amountOfRows;
  int32_t amountOfColumns;
  float** low;
  float** high;
} ArrayPairs;

void initializeArrayPairArray(ArrayPairs* AP, int32_t length, int32_t width){

  AP->amountOfRows = length;
  AP->amountOfColumns = width;

  AP->low = (float**)malloc(length * sizeof(float*));
  AP->high = (float**)malloc(length * sizeof(float*));

  for(int i=0; i<length; i++){
    AP->low[i] = (float*)malloc(width * sizeof(float));
    AP->high[i] = (float*)malloc(width * sizeof(float));
    for(int j=0; j<width; j++){
      AP->low[i][j] = 32;
      AP->high[i][j] = 44;
    }
  }
}

void addArrayPair(ArrayPairs* AP, float* low, float* high){
  AP->amountOfRows++;

  AP->low = (float**)realloc(AP->low, AP->amountOfRows * sizeof(float*));
  AP->high = (float**)realloc(AP->high, AP->amountOfRows * sizeof(float*));

  AP->low[AP->amountOfRows] = (float*)malloc(AP->amountOfColumns * sizeof(float));
  AP->high[AP->amountOfRows] = (float*)malloc(AP->amountOfColumns * sizeof(float));

  memcpy(AP->low[AP->amountOfRows], low, AP->amountOfColumns * sizeof(float));
  memcpy(AP->high[AP->amountOfRows], high, AP->amountOfColumns * sizeof(float));

  printf("TESTING PRINT: %.2f\n", AP->high[10][5]);
}

int main () {
  int32_t nrOfCols = 8;
  int32_t nrOfRows = 10;

  ArrayPairs arr;
  initializeArrayPairArray(&arr, nrOfRows, nrOfCols);

  int32_t mArrLength = 2;
  SomeMisc* mArr = (SomeMisc*)malloc(mArrLength*sizeof(SomeMisc));
  for(int i=0; i<mArrLength; i++){
    mArr[i].arr = (float*)malloc(nrOfCols*sizeof(float));
    for(int j=0; j<nrOfCols; j++){
      mArr[i].arr[j] = (i+1)*j;
    }
  }

  addArrayPair(&arr, mArr[0].arr, mArr[1].arr);

  printf("LOW:\tHIGH:\n");
  for(int i=9; i<arr.amountOfRows; i++){
    printf("INDEX: %d\n",i);
    for(int j=0; j<arr.amountOfColumns; j++){
      printf("%.2f\t%.2f\n",arr.low[i][j],arr.high[i][j]);
    }
    printf("\n");
  }

  return(0);
}

I followed this answer: 2d array realloc Segmentation Fault Error

But I already have the ArrayPairs* AP in the parameter list of addArrayPair, and the & with the object arr when calling the function.

I also tried dereferencing as was suggested in that answer, but this didn’t work either:

void addArrayPair(ArrayPairs* AP, float* low, float* high){
  (*AP).amountOfRows++;

  (*AP).low = (float**)realloc((*AP).low, AP->amountOfRows * sizeof(float*));
  (*AP).high = (float**)realloc((*AP).high, AP->amountOfRows * sizeof(float*));

  (*AP).low[AP->amountOfRows] = (float*)malloc((*AP).amountOfColumns * sizeof(float));
  (*AP).high[AP->amountOfRows] = (float*)malloc((*AP).amountOfColumns * sizeof(float));

  memcpy((*AP).low[(*AP).amountOfRows], low, (*AP).amountOfColumns * sizeof(float));
  memcpy((*AP).high[(*AP).amountOfRows], high, (*AP).amountOfColumns * sizeof(float));
}

>Solution :

You increase AP->amountOfRows too early. That means when you do AP->low[AP->amountOfRows] you will use an out-of-bounds index, and have undefined behavior

Instead (re)allocate AP->amountOfRows + 1 elements, and increase AP->amountOfRows once all allocations and copying is done:

void addArrayPair(ArrayPairs* AP, float* low, float* high){
  AP->low = realloc(AP->low, (AP->amountOfRows + 1) * sizeof(float*));
  AP->high = realloc(AP->high, (AP->amountOfRows + 1) * sizeof(float*));

  AP->low[AP->amountOfRows] = malloc(AP->amountOfColumns * sizeof(float));
  AP->high[AP->amountOfRows] = malloc(AP->amountOfColumns * sizeof(float));

  memcpy(AP->low[AP->amountOfRows], low, AP->amountOfColumns * sizeof(float));
  memcpy(AP->high[AP->amountOfRows], high, AP->amountOfColumns * sizeof(float));

  // Increase once all is done
  AP->amountOfRows++;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading