I'm having troubles understanding the C double-pointer concept. Essentially, I'm trying to write code which will check if record_1
hasn't been set yet. If not, set it. If it has been set, we'll add a new struct record newRecord
to the first records .next
pointer.
I'm using a double pointer because it's required by the professor
I've tried using firstRecord = malloc(sizeof(struct record*));
without any luck, as well as trying to dereference the firstRecord
.
The while loop to iterate through the records located in the addRecord
function also doesn't work as expected because I can't figure out how to deal with the double pointer.
struct record
{
int accountno;
char name[25];
char address[80];
struct record* next;
};
int addRecord (struct record ** firstRecord, int accountno, char name[], char address[])
{
if (firstRecord == NULL)
{
// Segmentation Fault here
// (*firstRecord)->accountno = accountno;
// Assign the name to the newRecord
// strcpy((*firstRecord)->name, name);
// Assign the name to the newRecord
// strcpy((*firstRecord)->address, address);
// Initialize the next record to NULL
// (*firstRecord)->next = NULL;
}
else
{
// Define a new struct record pointer named newRecord
struct record newRecord;
// Assign the accountno of newRecord
newRecord.accountno = accountno;
// Assign the name to the newRecord
strcpy(newRecord.name, name);
// Assign the address to the newRecord
strcpy(newRecord.address, address);
// Initialize the next record to NULL
newRecord.next = NULL;
// Create a new record and add it to the end of the database
struct record ** iterator = firstRecord;
// Iterate through the records until we reach the end
while (iterator != NULL)
{
// Advance to the next record
*iterator = (*iterator)->next;
}
// Assign the address of newRecord to the iterator.next property
(*iterator)->next = &newRecord;
}
return 1;
}
int main() {
struct record ** firstRecord;
firstRecord = NULL;
addRecord(firstRecord, 1, "Foo", "Bar");
addRecord(firstRecord, 2, "Foo", "Bar");
return 0;
}
It's not just required by the professor, it's required by your application. You want to allocate memory, and set a pointer that's defined outside your function to point to that memory. So naturally, you need to refer to that pointer. And C allows you to do that via a pointer to a pointer.
So what you want your calling code to look like is this:
struct record * firstRecord = NULL;
addRecord(&firstRecord, 1, "Foo", "Bar");
addRecord(&firstRecord, 2, "Foo", "Bar");
You pass the address of the regular pointer, so that addRecord
could write into it. And it does that by dereferencing its argument, like so:
int addRecord (struct record ** pFirstRecord, /* ... */ )
{
if (pFirstRecord == NULL)
return 0; // We weren't passed a valid address of a pointer to modify
if(*pFirstRecord == NULL)
{
// Here we check if the pointed to pointer already points to anything.
// If it doesn't, then proceed with adding the first record
}
}