Runtime Error with Printing Double Pointer Char Array - c

I am working on creating a system for entering student names and scores into arrays and printing the same information to the screen, unfortunately I keep getting the weird output.
I stepped through my program using a debugger and it showed that everything runs smooth until I get to the function that prints the student's information, there the double pointer char arrays have messed up values.
Here's an image of what I see when I run the program. (http://s28.postimg.org/nv29feawt/Error.png)
Note: Although I am aware that there are better and easier ways of doing this I am required to complete this assignment using dynamically allocated memory and arrays.
int main(void)
{
char **firstNames;
char **lastNames;
float *scores;
int recordsLength;
printf("Please indicate the number of records you want to enter: ");
scanf("%d", &recordsLength);
printf("\n\n");
firstNames = (char **)malloc(recordsLength * sizeof(char *));
lastNames = (char **)malloc(recordsLength * sizeof(char *));
scores = (float *)malloc(recordsLength * sizeof(float));
int i = 0;
while(i < recordsLength)
{
createNewEntry(i, firstNames, lastNames, scores);
i++;
}
printEntry(0, firstNames, lastNames, scores);
free(firstNames);
free(lastNames);
free(scores);
return 0;
}
void clearScreen()
{
#ifdef _WIN32
system("cls");
#elif _unix_
system("clear");
#endif
}
void printEntry(int entryID, char *firstNames[], char *lastNames[], float scores[])
{
clearScreen();
printf("|-------------------------------------------------------------------------|\n");
printf("| Student Entry |\n");
printf("|-------------------------------------------------------------------------|\n|\n");
printf("| First Name: %s Last Name: %s Score: %.1f\n|\n|\n|\n", firstNames[entryID], lastNames[entryID], scores[entryID]);
printf("|-------------------------------------------------------------------------|\n");
printf("| |\n");
printf("|-------------------------------------------------------------------------|\n\n");
}
void createNewEntry(int index, char *firstNames[], char *lastNames[], float scores[])
{
printf("Please input the records of the new student.\n\n\n");
char first[20];
char last[20];
float score = 100.0f;
printf("Please enter the student's first name: ");
scanf("%s", &first);
printf("\n\n");
printf("Please enter the student's last name: ");
scanf("%s", &last);
printf("\n\n");
printf("Please enter the student's score: ");
scanf("%f", &score);
printf("\n\n");
firstNames[index] = (char *)malloc((strlen(first)) * sizeof(char));
firstNames[index] = first;
lastNames[index] = (char *)malloc((strlen(last)) * sizeof(char));
lastNames[index] = last;
printf("first name: %s", firstNames[index]);
printf("last name: %s", lastNames[index]);
scores[index] = score;
}

firstNames[index] = (char *)malloc((strlen(first)) * sizeof(char));
firstNames[index] = first; /* You are missing your allocated memory block and assigning local */
Above lines are incorrect. You can not assign c-strings with assignation = operator. You should use strcpy for that.
You are assigning local array to firstnames, which has no life after the function ends. This invokes an undefined behavior. (You are seeing the strange characters, but it can be even worse).
Should be Re-written as (Similar for last name also)
firstNames[index] = malloc((strlen(first) + 1) * sizeof(char)); /* +1 for \0 */
if(firstNames[index] == NULL) {
/* Malloc failed, error handling */
...
}
/* else */
strcpy(firstNames[index], first); /* Use strcpy to copy contents */
Live example here
Before freeing firstNames and lastNames, you should free all the member of firstNames and lastNames in a loop.

I agree with the answer of Mohit Jain, adding to that you can even use sprintf.

Related

Char parameter in function is null or empty in C

I'm currently learning c, then I'm playing with functions and data types, specifically in this case char[]'s.
The following code I've written declares a function called verifyMessage() and receives two parameters, name and gender.
When I execute the function, I pass the two parameters that the user enters through the console, but when I print the name it doesn't print anything.
#include <stdio.h>
int main() {
int i = 0;
double controlNumber = 21200164;
double number = 0;
char name[50];
char gender[1];
int attempts = 5;
int aux = 0;
do {
printf("Introduzca el numero de control: ");
scanf("%lf", &number);
if (controlNumber == number) {
printf("\nWrite your name: ");
scanf("%s", name);
printf("\nWrite your gender (M/F): ");
scanf("%s", gender);
verifyMessage(name, gender);
break;
} else {
i++;
}
} while (i < attempts);
return 0;
}
void verifyMessage(char name[50], char gender[1]) {
if ('M' == gender[0]) {
printf("\n\Name: %s", name);//Here doesn´t print the name
printf("\nMen");
} else if ('F' == gender[0]) {
printf("\nWoman");
} else {
printf("\nInvalid gender");
}
}
Using char gender[1]; with %s is dangerous because gender has room for only one element, so it can accept only strings upto zero characters (the only room will be occupied by terminating null-character)
On the other hand, %s will read positive-length strings (it cannot read strings with zero characters), so it will cause out-of-range access on successful read.
Allocate enough elements and set the maximum length to read (upto the number of elements minis one for terminating null-character) to avoid buffer overrun.
char name[50];
char gender[2];
/* ... */
printf("\nWrite your name: ");
scanf("%49s", name);
printf("\nWrite your gender (M/F): ");
scanf("%1s", gender);
Checking results (return values) of scanf() to check if they successfully read desired things will improve your code more.

Pointer to structure in C

How can I display the stored values via pointer, my code outputs to NULL. I've already tried assigning the struct emp to ptr before the 2nd loop but it won't run.
struct rec {
char *Name;
}emp[100];
int main() {
int x;
int i;
struct rec *ptr = NULL;
ptr = emp;
printf("Enter Number of Clients: ");
scanf("%d", &x);
getchar();
for(i=0; i!=x; i++){
printf("Enter Name: ");
scanf("%[^\n]", &ptr->Name);
getchar();
ptr++;
printf("\n");
}
i = 0;
while(i!=x){
printf("Name is: %s\n", *ptr->Name);
i++;
ptr++;
}
If the code iterates twice it prints
Name: (NULL)
Name: (NULL)
How can I display the stored values via pointer, my code outputs to NULL. I've already tried assigning the struct emp to ptr before the 2nd loop but it won't run.
There are several issues in your code which are listed below:
You need to re-initialize your ptr pointer to the beginning of the array emp after the first loop.
ptr = emp;
Second one being data member name of your struct emp. It is just a pointer and it doesn't point towards a valid memory address where you can save user input cstring. Either you need to allocate the memory dynamically using malloc or use statically allocated memory just like shown below. However, you can have buffer overflow if you input characters more than DEFAULT_NAME_SIZE (including /0 character).
%[^\n] matches a char *, not a char **. You need to use scanf("%[^\n]", ptr->Name); not scanf("%[^\n]", &ptr->Name);.
"%s" format specifier of printf requires an arugment of type char * but you have been passing char type to it. The correct statement is printf("Name is: %s\n", ptr->Name);.
-
#include <stdio.h>
#define DEFAULT_NAME_SIZE 200
struct rec {
char Name[DEFAULT_NAME_SIZE];
} emp[100];
int main()
{
int x;
int i;
struct rec *ptr = NULL;
ptr = emp;
printf("Enter Number of Clients: ");
scanf("%d", &x);
getchar();
for (i=0; i< x; i++){
printf("Enter Name: ");
scanf("%[^\n]", ptr->Name);
getchar();
ptr++;
printf("\n");
}
ptr = emp;
for (i = 0; i < x; i++){
printf("Name is: %s\n", ptr->Name);
ptr++;
}
return 0;
}
You can try to enable all warning while you compile your code. Most of the bugs can be pointed by the compiler's warning message.
char *Name;
You never allocated space for the name. Did you mean
char Name[100]
?
This should work, until somebody enters too long of a name. You will get to buffer overflow later and learn about dynamic memory allocation.
When scanning or printing strings, we don't use & and * for referencing and dereferencing pointers, but we must also alloc and free space for them. Fixed your code:
#include <stdio.h>
#include <stdlib.h>
struct rec {
char *Name;
}emp[100];
int main() {
int x;
int i;
struct rec *ptr = NULL;
ptr = emp;
printf("Enter Number of Clients: ");
scanf("%d", &x);
getchar();
for(i=0; i!=x; i++)
{
printf("Enter Name: ");
/* alloc space for string pointer */
ptr->Name = (char*) malloc(sizeof(char)*10);
scanf("%s[^\n]",ptr->Name);
getchar();
ptr++;
printf("\n");
}
i = 0;
/* reset array pointer position */
ptr=emp;
while(i!=x)
{
printf("Name is: %s\n", (ptr->Name));
/* free space for string pointer */
free(ptr->Name);
i++;
ptr++;
}
}
PS: Remember resetting a pointer to the initial position whenever using pointers to arrays.

realloc: Program received signal SIGTRAP, Trace/breakpoint trap

I am working on a program that stores an arbitrarily long list of contacts (names and phone numbers). The entries are stored in an array that is resized each time a new element is added with the realloc function. The first contact can be added and displayed normally. However, when I try to add the second contact, the program crashes with the following message:
Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!RtlZeroHeap () (C:\WINDOWS\SYSTEM32\ntdll.dll)
No breakpoints have been set in my editor. The debugger says the problem is on the line containing the realloc statement. How can I fix this issue? I have included the relevant sections of code below.
#define STRING_LENGTH 32
typedef struct entry_t {
char name[STRING_LENGTH];
char number[STRING_LENGTH];
} Entry;
void *add_entry(Entry*, int);
int main()
{
int entry_count = 0;
Entry *entries = calloc(1, sizeof(Entry));
int choice = 0;
while (1) {
printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: ");
scanf(" %d", &choice);
switch (choice) {
case 1:
entries = add_entry(entries, entry_count++);
break;
// ...
}
}
}
void *add_entry(Entry *entries, int current_count)
{
Entry entry;
printf("Enter name: ");
scanf(" %[^\n]s", entry.name);
printf("Enter number: ");
scanf(" %[^\n]s", entry.number);
printf("\n");
entries[current_count] = entry;
return realloc(entries, sizeof(Entry) * (current_count + 1));
}
There is a logic problem here. You initially allocate space for one object with
calloc then call add_entry with the count equals to 0.
Then you add the new entry at index current_count which is 0 at this point.
Then you resize the memory with current_count + 1, which is also 1. So you are
not resizing the memory at all.
In the next iteration, entry_count is 1 and you add a new element at
entries[1]. And that's the problem, you are accessing the memory out of
bounds, because you still have space for only one object at this time.
Instead of reallocating by current_count + 1, you should reallocate by
current_count + 2, so that the next iteration has space to put the new
elements at the end of the memory.
void *add_entry(Entry *entries, int current_count)
{
Entry entry;
printf("Enter name: ");
scanf(" %[^\n]s", entry.name);
printf("Enter number: ");
scanf(" %[^\n]s", entry.number);
printf("\n");
entries[current_count] = entry;
return realloc(entries, sizeof(Entry) * (current_count + 2)); // <-- +2
}
Note that your current_count variable is always one step behind the real size of the allocation, that's why you need the +2
edit
Note also that the more natural way would be to resize first, and then insert
the new object. So I would initialize the memory with NULL and do it like
this:
int main()
{
size_t entry_count = 0;
Entry *entries = NULL, *tmp;
int choice = 0;
while (1) {
printf("Options:\n1) Add Entry\n2) Modify Entry\n3) Print Entries\n4) Exit\n\nSelect an option: ");
scanf(" %d", &choice);
switch (choice) {
case 1:
tmp = add_entry(entries, &entry_count);
if(tmp == NULL)
{
// error handling
// entries still point to the old memory
// could be useful in error handling
free(entries);
return 1;
}
entries = tmp;
break;
// ...
}
}
}
void *add_entry(Entry *entries, size_t *current_count)
{
if(current_count == NULL)
return NULL;
Entry entry;
printf("Enter name: ");
scanf(" %[^\n]s", entry.name);
printf("Enter number: ");
scanf(" %[^\n]s", entry.number);
printf("\n");
if(entries == NULL)
*current_count = 0;
Entry *tmp = realloc(entries, (*current_count + 1) * sizeof *entries);
if(tmp == NULL)
return NULL;
entries = tmp;
entries[(*current_count)++] = entry;
return entries;
}
Note here that the realloc and the increment of the counting variable
happens in the same function. Only when everything goes OK, you should increase
the counter. Also note that entries is initialized with NULL, because
realloc(NULL, size) is equivalent to malloc(size).

C compiler error: undefined reference to function

After I execute the exe I get this error :
undefined reference to `StudentScan'
error: ld returned 1 exit status|
Note: I'm bad and new to coding so don't mind my bad coding please^^
Note2: I'm just messing with random functions.
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main() {
int i;
int length;
struct student *studentp;
printf ("\nEnter the host of students: ");
scanf ("%d ", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
StudentScan(i,studentp);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
free (studentp);
void StudentScan(int i, struct student list[])
{ printf("\nEnter first name : ");
scanf("%s", list[i].firstName);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
return 0;
}
The posted code has defined StudentScan() within main(). But nested function definitions are not allowed in C. This should generate a compiler warning, such as:
warning: ISO C forbids nested functions [-Wpedantic]
void StudentScan(int i, struct student list[])
Pay attention to all compiler warnings and fix them. If no warning is seen when compiling this code, turn up the level of compiler warnings. On gcc, I suggest to always use at least gcc -Wall -Wextra, and I always add -Wpedantic. The -Wpedantic is needed with gcc to see a warning for this. Some compilers, and gcc is one of these, do support nested function definitions as a compiler extension. Still, this feature is nonstandard, and it is best to not rely on it.
The fix is simple: move the definition of StudentScan() out of main():
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main(void) {
int i;
int length;
struct student *studentp;
printf ("\nEnter the host of students: ");
scanf ("%d ", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
StudentScan(i,studentp);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
free (studentp);
return 0;
}
void StudentScan(int i, struct student list[])
{ printf("\nEnter first name : ");
scanf("%s", list[i].firstName);
printf("\nEnter average number: ");
scanf("%s", list[i].AverageNum);
}
Also note that you should always specify maximum widths when reading strings using scanf() family functions with %s or %[] to avoid buffer overflow. For example:
scanf("%19s", list[i].firstName);
Note that 19 is used, even though the firstName field is an array of 20 char values. Remember that one space must be reserved for the \0 terminator. And since you are using %s to read a string into the AverageNum field, you should also have:
scanf("%1s", list[i].AverageNum);
That is, this field can only hold one digit. If the intention is to hold two digits, this field must be changed within the struct to: char AverageNum[3].
And while we are discussing scanf(), note that this function returns the number of successful assignments made during the function call. If no assignments are made, 0 is returned. This return value should always be checked. Consider: if the user mistakenly enters a letter when a digit is expected, nothing is stored in the intended variable. This may lead to undefined behavior. You may try something like this to validate numeric input:
printf ("\nEnter the host of students: ");
while (scanf ("%d ", &length) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
This code asks the user to enter input again if a number is not entered when expected. Note that if the user does enter a non-digit, this character remains in the input stream and must be cleared before attempting to process more user input. The while loop is a typical construction which accomplishes this task.
Edit
Based on comments made by the OP, here is a modified version of the posted code. This version uses a float value instead of a character array for the AverageNum field of the struct. A floating-point type may be more useful than an integer type for storing averages. It is usually best to use double for floating-point values, but in this case it looks like AverageNum has little need for precision (the char array was intended to hold only two digits); float is probably sufficient for this use. If a different type is desired, it is simple enough to modify the code below.
Some input validation is implemented, but note that more could be done. The user is prompted to enter a number when non-numeric input is found where numeric input is expected. The input stream is cleaned with the while loop construction after such an input mistake; it would be good to remove this code to a separate function called clear_input(), for example.
If the user signals end-of-file from the keyboard, scanf() will return EOF; the code below chooses to exit with an error message rather than continue with malformed input in this case. This could also occur with input redirected from a file, and this condition may need to be handled differently if such input is expected.
The loop that populated the list[] array seemed to be operating inefficiently, asking for AverageNum twice in each pass. This has been streamlined.
Note that the call to malloc() can be rewritten as:
studentp = malloc(length * sizeof *studentp);
This is a very idiomatic way of writing such an allocation. Here, instead of using an explicit type as the operand of sizeof, that is, instead of sizeof (struct student), the variable which holds the address of the allocation is used. sizeof only uses the type of the expression *studentp, so this variable is not dereferenced here. Coding this way is less error-prone and easier to maintain when types change during the maintenance life of the code.
Yet, it is unclear why memory is allocated for studentp in the first place. In the posted code, both the firstName and AverageNum fields are filled for members of the dynamically allocated studentp in calls to StudentScan() in a loop; the same loop fills the AverageNum field of the members of list[] (a different array of structs) with different input. There seems to be no need for one of these arrays of student structs; I have commented-out the dynamically allocated array in favor of the statically allocated version.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
float AverageNum;
};
void StudentScan(int, struct student[]);
void StudentPrint(int, struct student[]);
int main(void) {
int i;
int length;
// struct student *studentp;
printf ("\nEnter the host of students: ");
while (scanf ("%d", &length) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
struct student list[length];
/* This is fine */
// studentp = malloc(length * sizeof (struct student));
/* But this is better */
// studentp = malloc(length * sizeof *studentp);
// if (studentp == NULL)
// {
/* Not wrong, but... */
// printf("Out of memory!");
// return 0;
// fprintf(stderr, "Allocation failure\n");
// exit(EXIT_FAILURE);
// }
for(i = 0; i < length; i++) {
StudentScan(i, list);
}
/* Code to display results here */
// free (studentp);
return 0;
}
void StudentScan(int i, struct student list[])
{
putchar('\n');
printf("Enter first name: ");
if (scanf("%19s", list[i].firstName) != 1) {
puts("Input error");
exit(EXIT_FAILURE);
}
printf("Enter average number: ");
while (scanf("%f", &list[i].AverageNum) < 1) {
puts("Please enter a number");
int c;
while ((c = getchar()) != '\n' && c != EOF) {
continue;
}
}
}
You have to remove the scan function from the main. Also there is not a printstudent function you are declaring. You must remove /n from the printf and the scanf functions and place them accordingly. You can then test if your data are being added correctly in your struct with a simple loop.
#include <stdio.h>
#include <stdlib.h>
struct student {
char firstName[20];
char AverageNum[2];
};
int main() {
int i=0;
int length;
struct student *studentp;
printf ("Enter the host of students:");
scanf ("%d", &length);
struct student list[length];
studentp=malloc(length*sizeof(struct student));
if (studentp==NULL)
{
printf("Out of memory!");
return 0;
}
for(i = 0; i < length; i++) {
printf("Enter first name :");
scanf("%s", list[i].firstName);
printf("Enter average number: ");
scanf("%1s", list[i].AverageNum);
}
for(i = 0; i< length; i++){
printf("number of host is: %d , his/her first name: %s , his/her avg number: %s \n", i, list[i].firstName, list[i].AverageNum);
}
free (studentp);
return 0;
}

How do I add a contact to a phonebook program in C?

For my intro to programming class, we have to code a phonebook in C that lets users add contacts, as well as delete and display them. It also has to allocate and free memory as necessary (I tried to do this, but I honestly don't really know what I'm doing).
Anyway, I cannot figure out how to add a contact to the phonebook. I've pasted the relevant part of the program so far. It compiles, but it crashes every time I try to add a contact. Once I get this figured out, I think I can get the rest of the functions without too much trouble. If anyone could help me out, I'd really appreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct entry {
char fname[20];
char lname[20];
char pnumber[20];
} entry;
// function prototypes
void addentry(int, entry*, char addfname[20], char addlname[20], char addpnumber[20]);
main() {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20] = { '\0' };
char addlname[20] = { '\0' };
char addpnumber[20] = { '\0' };
entry *pcontacts;
pcontacts = (entry*)calloc(1, (sizeof(entry)));
if (pcontacts == NULL) {
printf("No memory is available.");
free(pcontacts);
return 0;
}
while (1) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts);
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
pnum++;
printf("\nEnter first name: ");
scanf("%s", addfname);
printf("Enter last name: ");
scanf("%s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%s", addpnumber);
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
break;
}
} while (inputtest == 1);
}
}
void addentry(int pnum, entry *pcontacts, char addfname[20], char addlname[20], char pnumber[20]) {
pcontacts = (entry*)malloc(pnum * (sizeof(entry)));
if (pcontacts != NULL) {
strcpy(*pcontacts[pnum - 1].fname, addfname);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}
You get strings from standard input with scanf, but you should tell scanf the maximum number of bytes to store to the destination arrays to avoid buffer overruns:
scanf("%19s", addfname);
...
scanf("%19s", addlname);
...
scanf("%19s", addpnumber);
The way you call addentry is incorrect:
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
You actually try to read the byte just after the end of addfname, addlname and addpnumber. You should instead pass the arrays themselves, that will be passed to the function addentry as pointers to their first bytes:
addentry(pnum, pcontacts, addfname, addlname, addpnumber);
addentry should reallocate the array with realloc. It should be passed a pointer to the array pointer to it can update the pointer in main.
addentry does not copy the strings correctly: it only copies one, but with a syntax error.
Here is a corrected version:
void addentry(int, entry**, char addfname[20], char addlname[20], char addpnumber[20]);
int main(void) {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20];
char addlname[20];
char addpnumber[20];
entry *pcontacts = NULL;
for (;;) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts); /* OK for NULL */
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
printf("\nEnter first name: ");
scanf("%19s", addfname);
printf("Enter last name: ");
scanf("%19s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%19s", addpnumber);
addentry(pnum, &pcontacts, addfname, addlname, addpnumber);
pnum++;
break;
}
} while (inputtest == 1);
}
}
/* add an entry at position pnum */
void addentry(int pnum, entry **pp, char addfname[20], char addlname[20], char pnumber[20]) {
entry *pcontact = *pp;
pcontacts = realloc(pcontacts, (pnum + 1) * sizeof(entry));
if (pcontacts != NULL) {
*pp = pcontacts; /* update pointer in main */
strcpy(pcontacts[pnum].fname, addfname);
strcpy(pcontacts[pnum].lname, addlname);
strcpy(pcontacts[pnum].pnumber, addpnumber);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}

Resources