#include <stdio.h>
#include <stdlib.h>
struct packets
{
int source, destination, type, port;
char data[50];
};
int addpacket(int *, struct packets *);
void listpackets(int , struct packets *);
void save(int, struct packets *);
int main()
{
struct packets *info;
char choice;
int records = 0;
info = malloc(sizeof(struct packets));
do
{
puts("\n1. Add Packets\n"); //Menu with list of options.
puts("\n2. List all saved packets\n");
puts("\n3. Save packets\n");
puts("\n4. Clear all packet information\n");
puts("\nx. Exit the programme\n");
printf("\nPlease select your option: \n");
scanf("%c", &choice); //Reading the menu option entered.
if(choice == '\n') //if the choice is the new line character read again.
scanf("%c", &choice);
switch (choice)
{
case '1': system("cls"); //Clears the screen
puts("\nYou have selected to Add packet information, follow on-screen instructions\n"); records = addpacket(&records, info); //calls function "addpacket" and sents a copy of records and pointer to struct info.
break;
case '2': system("cls"); //clears the screen
puts("\nAll packet information will now be displayed on the screen\n"); listpackets(records, info);
break;
case '3': system("cls"); //clears the screen
puts("\nAll packet information will now be saved\n"); save(records, info);
break;
case '4': system("cls"); //clears the screen
puts("\nAll packet information will now be deleted\n");
break;
case 'x': puts("\nThe proframme will now close, Goodbye!\n"); //closes the programme.
break;
default : puts("\nIncorrect option, please select from menu\n"); //used if none of the menu options have been selected.
break;
}
}while (choice != 'x'); //The programme will run until the "x" option is entered at the menu.
return 0;
}
int addpacket(int *recCount, struct packets *info)
{
int validation = 0;
int stringlength = 0;
int i = 0;
char datatest[50];
do{
printf("\nPlease enter the source address: \n");
if (scanf("%i", &info[*recCount].source) == 1)
{
validation = 1;
}
else{
validation = 0;
getchar();
puts("\nThis is not a valid source address!\n");
}
}while (validation != 1);
printf("\nPlease enter destination address: \n");
scanf("%i", &info[*recCount].destination); //pointer to the destination address.
printf("\nPlease enter type: \n");
scanf("%i", &info[*recCount].type); // pointer to the address of the type.
printf("\nPlease enter the port: \n");
scanf("%i", &info[*recCount].port); //pointer to the port address.
printf("\nPlease enter data: \n");
scanf("%s", info[*recCount].data); //pointer to the data address.
*recCount ++; //adding one to record count
return *recCount; // returning the record count which will the be copied into records in main.
}
void listpackets(int records, struct packets *info)
{
int i;
for (i=0; i<records; i++){
printf("\nSource address: %i\n", info[i].source); //Displays the source address.
printf("\nDestination address: %i\n", info[i].destination); //Displays the destination address.
printf("\nType: %i\n", info[i].type); //Displays the type.
printf("\nPort: %i\n", info[i].port); //displays the port.
printf("\nData: %s\n", info[i].data); //displays the data information.
}
}
void save(int records, struct packets *info)
{
FILE *savedfile;
char filename[30] = { '\0'}; //this is where the file name will be stored.
int i;
printf("\nPlease enter a filename: \n");
scanf("%s", filename);
if ((savedfile = fopen(filename, "w")) == NULL)
{
printf("\n%s could not be opened\n", filename);
exit(1);
}
else
{
for (i=0; i<records; i++)
fprintf(savedfile, "%i %i %i %i %s", info[i].source, info[i].destination, info[i].type, info[i].port, info[i].data);
}
fclose(savedfile);
}
我调用时,我的save和listpacket函数崩溃了。这工作得早,直到我将malloc引入我的程序并进行一些基本的输入验证。我认为这可能是指针的问题。我的程序编译没有错误/警告所以我坚持问题可能是什么。随意尝试编译程序,看看我的意思。任何帮助都会非常感激,因为我正在努力解决这个问题。
答案 0 :(得分:2)
您正在使用malloc()
为单个struct packets
分配空间。您稍后会将info
指针视为records
这样的结构数组......您将超出已分配空间的边界。
有关一种潜在方式的详细信息(将自动增长您的阵列):
// change the signature of addpacket():
int addpacket(int *, struct packets **);
...
// change how add packet gets called:
records = addpacket(&records, &info);
// change addpacket():
int addpacket(int *recCount, struct packets **callerinfo)
{
...
// grow the buffer by one record
*callerinfo = realloc(*callerinfo, (*recCount + 1) * sizeof (**callerinfo));
struct packets *info = *callerinfo; // to avoid changing other code
... no other changes, just the rest of your routine
}
那将会接近,而不是完全解决它。
完整的计划,为我工作:
#include <stdio.h>
#include <stdlib.h>
struct packets
{
int source, destination, type, port;
char data[50];
};
int addpacket(int *, struct packets **);
void listpackets(int , struct packets *);
void save(int, struct packets *);
int main()
{
struct packets *info;
char choice;
int records = 0;
info = malloc(sizeof(struct packets));
do
{
puts("\n1. Add Packets\n"); //Menu with list of options.
puts("\n2. List all saved packets\n");
puts("\n3. Save packets\n");
puts("\n4. Clear all packet information\n");
puts("\nx. Exit the programme\n");
printf("\nPlease select your option: \n");
scanf("%c", &choice); //Reading the menu option entered.
if(choice == '\n') //if the choice is the new line character read again.
scanf("%c", &choice);
switch (choice)
{
case '1': system("cls"); //Clears the screen
puts("\nYou have selected to Add packet information, follow on-screen instructions\n"); records = addpacket(&records, &info); //calls function "addpacket" and sents a copy of records and pointer to struct info.
break;
case '2': system("cls"); //clears the screen
puts("\nAll packet information will now be displayed on the screen\n"); listpackets(records, info);
break;
case '3': system("cls"); //clears the screen
puts("\nAll packet information will now be saved\n"); save(records, info);
break;
case '4': system("cls"); //clears the screen
puts("\nAll packet information will now be deleted\n");
break;
case 'x': puts("\nThe proframme will now close, Goodbye!\n"); //closes the programme.
break;
default : puts("\nIncorrect option, please select from menu\n"); //used if none of the menu options have been selected.
break;
}
}while (choice != 'x'); //The programme will run until the "x" option is entered at the menu.
return 0;
}
int addpacket(int *recCount, struct packets **callerinfo)
{
int validation = 0;
int stringlength = 0;
int i = 0;
char datatest[50];
*callerinfo = realloc(*callerinfo, (*recCount + 1) * sizeof (**callerinfo));
struct packets *info = *callerinfo; // to avoid changing other code
do{
printf("\nPlease enter the source address: \n");
if (scanf("%i", &info[*recCount].source) == 1)
{
validation = 1;
}
else{
validation = 0;
getchar();
puts("\nThis is not a valid source address!\n");
}
}while (validation != 1);
printf("\nPlease enter destination address: \n");
scanf("%i", &info[*recCount].destination); //pointer to the destination address.
printf("\nPlease enter type: \n");
scanf("%i", &info[*recCount].type); // pointer to the address of the type.
printf("\nPlease enter the port: \n");
scanf("%i", &info[*recCount].port); //pointer to the port address.
printf("\nPlease enter data: \n");
scanf("%s", info[*recCount].data); //pointer to the data address.
++(*recCount); //adding one to record count
return *recCount; // returning the record count which will the be copied into records in main.
}
void listpackets(int records, struct packets *info)
{
int i;
for (i=0; i<records; i++){
printf("\nSource address: %i\n", info[i].source); //Displays the source address.
printf("\nDestination address: %i\n", info[i].destination); //Displays the destination address.
printf("\nType: %i\n", info[i].type); //Displays the type.
printf("\nPort: %i\n", info[i].port); //displays the port.
printf("\nData: %s\n", info[i].data); //displays the data information.
}
}
void save(int records, struct packets *info)
{
FILE *savedfile;
char filename[30] = { '\0'}; //this is where the file name will be stored.
int i;
printf("\nPlease enter a filename: \n");
scanf("%s", filename);
if ((savedfile = fopen(filename, "w")) == NULL)
{
printf("\n%s could not be opened\n", filename);
exit(1);
}
else
{
for (i=0; i<records; i++)
fprintf(savedfile, "%i %i %i %i %s\n", info[i].source, info[i].destination, info[i].type, info[i].port, info[i].data);
}
fclose(savedfile);
}