简体   繁体   中英

Trouble allocating array of structs

My code segfaults whenever I try to access the structs data members. This has to be because it is not properly allocated. I do not know why this isn't working. The struct looks like it is defined correctly. The malloc looks like it is set up correctly. I use correct format to access the data. However it just segfaults whenever I try to access anything.

struct fracBlock {
  struct fracBlock *next ;
  fraction frac ;
} ;

static struct fracBlock *fbp ;

void init_heap(void){ fbp = NULL ; }

fraction *new_frac(void){
  struct fracBlock **tempBlock ;
  struct fracBlock *prev ;
  struct fracBlock *curr ;
  fraction *tempFrac ;
  fraction testFrac ;
  int i ;
//if free list is empty malloc 10 blocks
  if ( fbp == NULL ){
    tempBlock = ( struct fracBlock** )malloc(10*sizeof(struct fracBlock)) ;

  //if no more space left
  if ( tempBlock == NULL ) {
    printf( "\nError: No more memory space left for allocation!\n" ) ;
    exit(1) ;
  }

  tempBlock[0]->next = tempBlock[1] ;
  tempBlock[1]->next = tempBlock[2] ;
  tempBlock[2]->next = tempBlock[3] ;
  tempBlock[3]->next = tempBlock[4] ;
  tempBlock[4]->next = tempBlock[5] ;
  tempBlock[5]->next = tempBlock[6] ;
  tempBlock[6]->next = tempBlock[7] ;
  tempBlock[7]->next = tempBlock[8] ;
  tempBlock[8]->next = NULL ;
  *tempFrac = tempBlock[9]->frac ;

  return tempFrac ;
}

You have a number serious bugs in the posted code.

1) There is missing a }

2) tempfrac is an uninitialized pointer but you do *tempfrac = ... That is undefined behavior so any thing may happen. A crash is likely. Maybe you forgot to malloc memory like tempfrac = malloc(sizeof *tempfrac);

3) Even if tempfrac is assigned using malloc the line *tempFrac = tempBlock[9]->frac ; is still wrong because frac in block 9 is also uninitialized. The code makes no sense.. it tries to return (a pointer to) an uninitialized value.

4) The use of double pointer is just wrong. The code should be more like:

  struct fracBlock *tempBlock ;  // Single *

  if ( fbp == NULL ){
    tempBlock = malloc(10*sizeof *tempBlock) ;

    //if no more space left
    if ( tempBlock == NULL ) {
      printf( "\nError: No more memory space left for allocation!\n" ) ;
      exit(1) ;
    }

    tempBlock[0].next = tempBlock + 1; // or tempBlock[0].next = &tempBlock[1];
    tempBlock[1].next = tempBlock + 2;
    ...

5) You never update fbp In other words, the malloc you do is into a pointer that goes out of scope when the function completes. So you have a memory leak. Most likely you shouldn't use a local variable tempBlock but instead operate directly on fbp . Like:

  if ( fbp == NULL ){
    fbp = malloc(10*sizeof *fbp) ;

    //if no more space left
    if ( fbp == NULL ) {
      printf( "\nError: No more memory space left for allocation!\n" ) ;
      exit(1) ;
    }

    fbp[0].next = fbp + 1;
    fbp[1].next = fbp + 2;
    ...

That said, notice that global variables are nearly always a bad thing. Avoid them.

I think these are the problems, but someone please call me out if I made a mistake.

If I have an integer array, I allocate it in this manner:

int * x ; // Array of length 3
x = ( int * ) malloc( 3 * sizeof( int ) ) ;

I cast x as int * because malloc will return an address in the heap, and I want that address to be interpreted as a pointer to an integer. However, I use int inside the malloc call since I want to allocate enough space for 3 int types.

So, you'll want to use sizeof( struct fracBlock * ) instead of sizeof( struct fracBlock ) for that reason. You'll also need to allocate space for each of the elements of that array with malloc calls. This is because each element of the array is a pointer, and when you allocate it, it isn't necessarily pointing to any space you've been allocated yet.

Also, I think you need to allocate space for tempFrac with another malloc call. You dereference the pointer when assigning it a value, but heap space has not been allocated, leading to a segfault since you do not necessarily have permission to write to that memory.

The real solution though... garbage collection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM