George D
George D

Reputation: 1

How do I pass an array of Pointers to a structure and allocate the members

ok, heres my code. I'm trying to pass an array of pointers to a structure to a function. I need to dynamically allocate each structure and put a pointer to that structure in the array. When I malloc the second time thru it gets a heap error. HELP

#define MAXSTRUCTS 50
#define MAXBUFF 100


typedef struct {  
 char fullName[41];  
 char address[41];  
 char cityState[41];  
 char zipcode[11];  
} Persons;  

int readData(Persons *structPtrs[]);

int main(void) {

     int totalStructs;  
     Persons *structPtrs[MAXSTRUCTS];  
     totalStructs = 0;  
     structPtrs[0] = NULL;  
     totalStructs = readData(structPtrs);  
}

int readData(Persons *strptr[]) {

    int tStructs = 0;  
    int recs;  
    char inRecord[MAXBUFF];  
    Persons *tmpPtr;  
    tStructs = 0;  
    for (recs=0; recs < MAXSTRUCTS; recs++) {  
        if (gets(inRecord) != NULL) {  
           strptr[recs] = (Persons *)malloc( sizeof(Persons));  
           tmpPtr = strptr[recs];  
           strncpy(tmpPtr->fullName,inRecord,MAXBUFF);  
           gets(inRecord);  
           strncpy(tmpPtr->address,inRecord,MAXBUFF);  
           gets(inRecord);  
           strncpy(tmpPtr->cityState,inRecord,MAXBUFF);  
           gets(inRecord);  
           strncpy(tmpPtr->zipcode,inRecord,MAXBUFF);  
           strptr[recs] = tmpPtr;  
           tStructs++;  
        }  
        else {  
             if ( recs = 0 ) {  
                exit (0);  
             }  
             recs=MAXSTRUCTS;  
        }  
    }  
    return(tStructs);  
}  

Upvotes: 0

Views: 263

Answers (2)

Mahesh
Mahesh

Reputation: 34625

 int readDataToRecord( Persons *eachEntry[] ) {

int numEntries = 0 ;

Persons *tempPtr ;

for( int i=0 ; i < NUM_OF_RECORDS; ++i ) {

    eachEntry[i] = ( Record * ) malloc( sizeof( Record ) ) ;
    memset( eachEntry[i], 0, sizeof( Record ) ) ;

    tempPtr = eachEntry[i] ;

    fgets( tempPtr->firstName,  sizeof( tempPtr->firstName ), stdin ) ;
    fgets( tempPtr->secondName, sizeof( tempPtr->secondName), stdin ) ;

    eachEntry[i] = tempPtr ;

    ++numEntries ;
}

return numEntries ;

}

This would also efficiently do the job. Once you have new record, you would any how have the memory allocated for each of its member. So you can directly fgets to that variable.

@Vlad : Please let me know if I am wrong.

Upvotes: 1

user405725
user405725

Reputation:

You are doing everything right in regard of passing an array of pointers and allocating memory. What leading to a heap corruption is incorrect usage of strncpy function. The arrays where you are trying to copy data to are slightly smaller than MAXBUFF in all cases. To fix this, you have to specify the size of destination array instead of MAXBUFF. For example, instead of:

strncpy(tmpPtr->fullName,inRecord,MAXBUFF); 

... do (assuming that buffer is already filled with \0 symbols):

strncpy(tmpPtr->fullName,inRecord, sizeof(tmpPtr->fullName) - 1); 

Also, using gets function is not recommended as well as it could easily lead to buffer overruns. Try using fgets instead.

Here is your modified example that works:

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

#define MAXSTRUCTS 2
#define MAXBUFF 100

typedef struct {
  char fullName[41];
  char address[41];
  char cityState[41];
  char zipcode[11];
} Persons;

int readData(Persons *structPtrs[]);

int main ()
{
  int totalStructs;
  int recs;
  Persons *structPtrs[MAXSTRUCTS];
  totalStructs = 0;
  structPtrs[0] = NULL;
  totalStructs = readData(structPtrs);
  for(recs = 0; recs < totalStructs; ++recs) {
    printf ("Record #%d - %s\n", recs + 1, structPtrs[recs]->fullName);
  }
  return 0;
}

int readData(Persons *strptr[])
{
  int tStructs = 0;
  int recs;
  char inRecord[MAXBUFF];
  Persons *tmpPtr;
  tStructs = 0;
  for (recs=0; recs < MAXSTRUCTS; ++recs) {
    memset (inRecord, 0, sizeof(inRecord));
    if (fgets(inRecord, sizeof (inRecord) - 1, stdin))
      {
      strptr[recs] = (Persons *)malloc(sizeof(Persons));
      tmpPtr = strptr[recs];
      memset (tmpPtr, 0, sizeof(Persons));
      strncpy(tmpPtr->fullName,inRecord,sizeof(tmpPtr->fullName) - 1);
      fgets(inRecord, sizeof (inRecord) - 1, stdin);
      strncpy(tmpPtr->address,inRecord,sizeof(tmpPtr->address) - 1);
      fgets(inRecord, sizeof (inRecord) - 1, stdin);
      strncpy(tmpPtr->cityState,inRecord, sizeof(tmpPtr->cityState) - 1);
      fgets(inRecord, sizeof (inRecord) - 1, stdin);
      strncpy(tmpPtr->zipcode,inRecord, sizeof (tmpPtr->zipcode) - 1);
      strptr[recs] = tmpPtr;
      tStructs++;
    } else {
      if ( recs = 0 ) {
    exit (0);
      }
      recs=MAXSTRUCTS;
    }
  }
  return(tStructs);
}

Upvotes: 1

Related Questions