Reputation: 1
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
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
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