My program crashes, and I don't understand why - c

I am coding a record-keeping program in C using binary file handling. I am using Code::Blocks, with gcc to compile my C program on Windows 8.
When the program reaches to the following block, an error-message appears:
My code:
int dispaly(student record[], int count)
{
/*
This is what structure `student` looks like:
int id;
char name[200], phone[20], address[200], cclass[50];
char sec[20], roll[50], guardian_name[200], relation[200] ;
char p2_colg[100], slc_school[200];
float plus2_percent, slc_percent;
struct date dob;
struct date enr_date;
struct date looks like
int day, month, year;
*/
printf("Reached"); /*Program Runs Fine upto here*/
int i = 0;
for(i=0; i<count; i++)
{
printf("\nId: %d\tPhone: %s\nName: %s\nAddress: %s"
"\nClass: %s\tSection: %s\nRoll: %s\nGuardian Name: %s\tRelation:%s"
"\nPlus-Two in: %s\tPercentage:%f\nSLC School: %s\tPercentage: %f"
"\nDate Of Birth(mm/dd/yyyy): %d/%d/%d"
"\nEnrolled in (mm/dd/yyyy): %d/%d/%d\n\n---------------------------------------\n", record[i].id, record[i].name, record[i].address
, record[i].cclass, record[i].sec, record[i].roll, record[i].guardian_name, record[i].relation, record[i].p2_colg
, record[i].plus2_percent, record[i].slc_school, record[i].slc_percent, record[i].dob.month, record[i].dob.day, record[i].dob.year
, record[i].enr_date.month, record[i].enr_date.day, record[i].enr_date.year);
}
getch();
return 0;
}
The program compiles without any errors or warnings.
What's going on?

Hard to tell exactly what crashed without looking at the exact data in your array, but you forgot "phone" in the arguments list to printf, which could certainly result in a crash inside printf.

There's not a terribly good reason to stack those all up into one call. It would have been easier to spot your bug of the missing "phone" if you separated each line out into its own printf. Also, you could cut down on the redundancy if you captured record[i] into a pointer.
Contrast with:
student * r = &record[i];
printf("\n");
printf("Id: %d\tPhone: %s\n", r->id, r->phone);
printf("Name: %s\n", r->name);
printf("Address: %s\n", r->address);
printf("Class: %s\tSection: %s\n", r->cclass, r->sec);
printf("Roll: %s\n", r->roll);
printf("Guardian Name: %s\tRelation:%s\n", r->guardian_name, r->relation);
printf("Plus-Two in: %s\tPercentage:%f\n", r->p2_colg, r->plus2_percent);
printf("SLC School: %s\tPercentage: %f\n", r->slc_school, r->slc_percent);
printf("Date Of Birth(mm/dd/yyyy): %d/%d/%d\n",
r->dob.month, r->dob.day, r->dob.year);
printf("Enrolled in (mm/dd/yyyy): %d/%d/%d\n"
r->enr_date.month, r->enr_date.day, r->enr_date.year);
printf("\n");
printf("---------------------------------------\n");
In a technical sense, making multiple calls to printf will incur some function call overhead. And declaring a pointer variable for the current student in the array will incur some storage space. But it is basically negligible, and of no consequence in a case like this. Under the hood, the output is buffered anyway.

Related

Getting weird output in c with structures

I'm new to C programming and just doing homework, thing is, I cant figure out why this the choice "Visualizar platos del dia" outputs weird symbols and not the things that I've input in with the cargar structure.
#include <stdio.h>
#include <string.h>
#include <strings.h>
struct platos{
char aperitivo[40];
char plato1[40];
char plato2[40];
char postre[40];
char bebida1[40];
char bebida2[40];
char bebida3[40];
};
void cargar(struct platos a);
void vis(struct platos a);
void emit(struct platos a);
int main(){
int a=0, b=0;
struct platos plato;
do{
printf("Bienvenido a restaurante 'Senior bigotes'\n\n");
printf("1:Cargar platos del dia\n");
printf("2:VIsualizar platos del dia\n");
printf("3:Emitir comanda y factura\n");
printf("4:Salir\n");
scanf("%d", &a);
switch(a){
case 1: cargar(plato);
break;
case 2: vis(plato);
break;
case 3: emit(plato);
break;
case 4:
b++;
break;
}
}while(b<1);
return 0;
}
void cargar(struct platos a){
printf("Ingrese aperitivo\n");
__fpurge(stdin);
gets(a.aperitivo);
printf("Ingrese plato 1\n");
__fpurge(stdin);
gets(a.plato1);
printf("Ingrese plato 2\n");
__fpurge(stdin);
gets(a.plato2);
printf("Ingrese postre\n");
__fpurge(stdin);
gets(a.postre);
printf("Ingrese bebida 1\n");
__fpurge(stdin);
gets(a.bebida1);
printf("Ingrese bebida 2\n");
__fpurge(stdin);
gets(a.bebida2);
printf("Ingrese bebida 2\n");
__fpurge(stdin);
gets(a.bebida3);
}
void vis(struct platos a){
printf("\nAperitivo: %s", a.aperitivo);
printf("\nPlato 1: %s", a.plato1);
printf("\nPlato 2: %s", a.plato2);
printf("\nPostre: %s", a.postre);
printf("\nBebidas: %s | %s | %s\n", a.bebida1, a.bebida2, a.bebida3);
int c = getchar();
}
void emit(struct platos a){
printf("\nAperitivo: %s $10", a.aperitivo);
printf("\nPlato 1: %s $25", a.plato1);
printf("\nPlato 2: %s $35", a.plato2);
printf("\nPostre: %s $20", a.postre);
printf("\nBebidas: %s | %s | %s $15\n", a.bebida1, a.bebida2, a.bebida3);
printf("Total: $105");
int c = getchar();
}
I'm using manjaro btw with visual code. I asked the teacher and he wants me to debug the code but Idk how to do that in visual code. Any help?
If you mean Visual Studio Code, it has a Run menu item that contains the the debugging items, such as Toggle Breakpoint and Start Debugging.
The first can be used on the statement you want to start debugging with, and the second to start running your code. Once the breakpoint is hit, there should be a small panel on the screen somewhere with controls for continue, step over, step into, and so on:
If you hover over those controls, it should also show you the equivalent keyboard commands you can use.
However, you should be aware that, for your immediate problem, structures are passed by value in C, not by reference. That means that the cargar function gets a copy of plato and populates the fields of that copy.
Then that copy is thrown away when returning from cargar, leaving the original plato with the arbitrary field it was given at creation time. So, when that is subsequently passed to vis or emit, you won't see the data you entered.
The easiest solution is probably to pass a pointer (&plato) to cargar, and use -> rather than . to access the fields within that function. In other words, something like (see notes below as to why I'm using fgets()):
switch (a) {
case 1: cargar(&plato); break;
and
void cargar(struct platos const *a_ptr){
printf("Ingrese aperitivo\n");
__fpurge(stdin);
fgets(a_ptr->aperitivo, sizeof(a_ptr->aperitivo), stdin);
// And so on for the other fields ...
That particular const before *a_ptr applies to the pointer value itself rather than the value "behind" the pointer. You need to be able to change the value since that's the whole purpose of the function.
However, I'd also do something similar for vis() and emit() so as to not be copying large structures around but I'd use (for example):
void vis(const struct platos const *plato) {
to make it clear neither the pointer nor the value behind the pointer is expected to change.
And, as others have mentioned in comments, you should use fgets() rather than gets(), there is no way to use the latter safely. If you want to know how to use it for user input, see this answer.
It should be an indication of how bad gets() is considered that it's actually been deprecated and removed from the standard.

Segmentation fault while function call

I got a struct Chat
struct Chat
{
int m_FD;
int m_BindPort;
char m_NameLength;
char* m_Name;
char m_PeerCount;
char** m_PeerList;
} typedef Chat_t;
i'm initializing it with this function:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen+1));
strcpy(this->m_Name, name);
this->m_BindPort = bindPort;
this->m_PeerCount = peerCount;
this->m_PeerList = malloc(sizeof(char*) * peerCount);
for(int i=0; i<peerCount; i++)
{
this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
strcpy(this->m_PeerList[i], peerList[i]);
}
//Socket initialization for TCP connection...
//Commenting this out doesn't change anything so i'm hiding it for simplification
return 0;
}
After that i'm calling a second function
int chat_communicate(Chat_t* this)
{
printf("2\n");
fflush(stdout);
//Some stuff that doesn't matter because it isn't even called
return retVar;
}
in main like this
void main(void)
{
char* peerList[1];
char username[USERNAME_MAX_LEN];
int initRet;
int loopRet;
Chat_t chat;
peerList[0] = "192.168.2.2";
memset(username, 0, USERNAME_MAX_LEN);
printf("Please enter your user name: ");
scanf("%s", username);
username[USERNAME_MAX_LEN-1] = 0;
initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);
printf("File Descriptor: %d\n", chat.m_FD);
printf("Binding Port: %d\n", chat.m_BindPort);
printf("Name Length: %d\n", chat.m_NameLength);
printf("Name: %s\n", chat.m_Name);
printf("Peer Count: %d\n", chat.m_PeerCount);
for(int i=0; i< chat.m_PeerCount; i++)
{
printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
}
printf("1");
ret = chat_communicate(&chat);
//Even more Stuff that isn't even called
}
My program outputs the following
File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault
It compiles without errors or even warnings.
You can also assume that every string is null-Terminated The stuff i replaced with comments itn't that complicated but just too much to show.
Every value inside the struct is printed with printf right before but when passing this very struct per reference the application crashes.
What i want to know is why i'm getting this Segmentation Fault. Since it appeared while calling a function i thought it is some kind of layout problem but i havn't find anything like that.
Addition:
Because some people weren't able to believe me that the code i hid behind "some stuff" comments doesn't change anything i want to state this here once again. This code just contains a tcp socket communication and only performs read-operations. I also am able to reproduce the error mentioned above without this code so please don't get stuck with it. Parts does not influence the object under observation at all.
Among other potential problems,
this->m_PeerList = malloc(sizeof(char)*peerCount);
is clearly wrong.
m_PeerList is a char **, yet you're only allocating peerCount bytes, which only works if a char * pointer is one byte on your system - not likely.
Replace it with something like
this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );
Note that sizeof( char ) is always one - by definition.
You're not allocating enough memory for the this->m_Name. It should be on more than this if you want it to store the null-terminated string of the name.
That, or we need more information about the peerList.
Now that you have posted an almost complete code, I was able to spot two problems next to each other:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
//< this->m_Name = malloc(sizeof(char) * nameLen); // wrong
strcpy(this->m_Name, name); // correct
//< memcpy(this->m_Name, name, nameLen); // wrong
...
The lines starting with //< is your original code:
Here you don't allocate enough space, you need to account for the NUL terminator:
this->m_Name = malloc(sizeof(char) * nameLen);
And here you don't copy the NUL terminator:
memcpy(this->m_Name, name, nameLen);
You really need to be aware how strings work in C.
Why don't you debug it yourself. If using GCC, compile your code with options -g -O0. Then run it with gdb:
gdb ./a.out
...
(gdb) r
If it crashes do:
(gdb) bt
This will give exactly where it crashes.
Update: There may be potential problems with your code as found by other users. However, memory allocation related issues will not crash your application just on calling function chat_communicate. There could be different reasons for this behaviour ranging from stack overflow to improper compilation. Without seeing the whole code it is very difficult to tell. Best advice is to consider review comments by other users and debug it yourself.

C program \n and while loop

guys I have a C program question. My goal is to make a change operation working for taking a price and giving out the current amount remaining. I code in java, so this is my first time in C, Im not looking to have my entire code done for me. I can do the code, however im having trouble getting it to execute the way I want. My problem here is that when I use \n my code seems to work, but my output is really weird, i have to add constant spaces and repeat my lines. not sure why this is happening, Also my while loop does not seem to execute, which is making no sense to me. If anyone could help , I would apprectiate it. Thank you for reading, ps I reply isntantly
/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
/* Header comment that describes the purpose of the program
* Name Karanvir Dhillon
* Date Jan 12
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (void) {
double tendered;
double changeDue;
double price;
int hundred=0;
int twenty=0;
int ten=0;
int five=0;
int toonoe=0;
int loonie=0;
int quarter=0;
int dime=0;
int nickle=0;
int penny=0;
/* Statements to be executed */
printf("Total purchase price and tendered amount\n");
scanf("%lf %lf ", &price, &tendered);
printf(" %lf and %lf is \n", tendered,price);
changeDue=tendered-price;
printf("%lf \n", changeDue);
if(tendered<price){
printf("Not enough money recieved as payment \n");
}
if(tendered==price){
printf("Exact payment, no change given \n");
}
if(tendered>price){
printf("%lf Amount to be paid is \n", changeDue);
}
while(changeDue!=0.00){
if(changeDue<=100.00){
changeDue=changeDue-100.00;
hundred=hundred+1;
}
if(changeDue<=20.00){
changeDue=changeDue-20.00;
twenty=twenty+1;
}
if(changeDue<=10){
changeDue=changeDue-10.00;
ten=ten+1;
}
if(changeDue<=5){
changeDue=changeDue-5.00;
five=five+1;
}
if(changeDue<=2){
changeDue=changeDue-2.00;
toonoe=toonoe+1;
}
if(changeDue<=1){
changeDue=changeDue-1.00;
loonie=loonie+1;
}
if(changeDue>1){
for(int i=0;i<changeDue;i++){
if(i==0.25&&changeDue>=0.25){
changeDue=changeDue-0.25;
quarter=quarter+1;
}
if(i==0.10&&changeDue>=0.10){
changeDue=changeDue-0.10;
dime=dime+1;
}
if(i==0.05&&changeDue>=0.05){
changeDue=changeDue-0.05;
nickle=nickle+1;
}
if(i==0.01&&changeDue<0.05){
changeDue=changeDue-0.01;
penny=penny+1;
}
}
}
}
if(hundred!=0){
printf("%d hundred$ bills given as change \n",hundred);
}
if(twenty!=0){
printf("%d twenty$ bills given as change \n",twenty);
}
if(ten!=0){
printf("%d ten$ bills given as change \n",ten);
}
if(five!=0){
printf("%d five$ bills given as change \n",five);
}
if(toonoe!=0){
printf("%d toonie coins given as change \n",toonoe);
}
if(loonie!=0){
printf("%d loonie coins given as change \n",loonie);
}
if(quarter!=0){
printf("%d quarter coins given as change \n",quarter);
}
if(dime!=0){
printf("%d dime coins given as change \n",dime);
}
if(nickle!=0){
printf("%d nicke coins given as change \n",nickle);
}
if(penny!=0){
printf("%d penny coins given as change \n",penny);
}
return 0;
}
In most C compilers, including ours, the newline escape sequence '\n' yields an ASCII line feed character. The C escape sequence for a carriage return is '\r'.
Include a '\r' along with (or perhaps instead of) the '\n' in output strings. For example:
printf("Hello world\r\n");

C program stops in the middle of running

Hi im new here also im new to programming and id like you to help me on this : to problem is that after compiling and running the program it stops in the middle of it when running and i didnt know what is causing this and sorry for the unreadable previous post :
here is my program :
char answer[15];
char place[15];
char fullname[15];
int age;
printf("What Is Your Full Name?: ");
scanf("%s",fullname);
printf("What Is Your Age?: ");
scanf("%d",age);
printf("Where Do You Live?: ");
scanf("%s",place);
if(strcmp(place,"gafsa")==0) {
printf("Aint a bad place you know");
}
else{
printf("hmmm %s cool\n",place);
}
printf("your name is %s, %d year old from %s is that right?: ",fullname,age,place);
scanf("%s",answer);
if(strcmp(answer,"yes")==0){
printf("you my friend are awesome\n");
}
else{
printf("you suck\n");
}
and this is an image to show the problem clearly:
http://i.stack.imgur.com/yFTwK.png
You need to pass the address of the variable:
scanf("%d",&age);
^
You're taking input at a memory location of value of uninitialized age. i.e. some garbage
Use:
scanf("%d",&age); // notice & , pass address of variable age

C programming opening and reading from a file

int main(void){
FILE *ifp; //input file pointer
int totalClock; //total clock count
// BEGIN OPERATIONS=============================
ifp=fopen("prog1.asy.txt", "r");
system("PAUSE");
assert(ifp!=NULL);
//populate the instMem with inst===================
int i=0;
//system("PAUSE");
for (i=0;i<512;i++)
{
inst temp=parser(ifp);
if (temp.opcode==-1)
break;
instMem[i]=temp;
printf("%s\n", instMem[i].rawCode);
}
printf("\n%d instructions parsed\n", i-1);
system("PAUSE");// PAUSE TO CHECK CODE PARSING IS CORRECT========
int cont=0;
while (cont==0){
//begin sim================================================
//initialize the mem=======================================
int i;
for (i=0;i<512;i++)
data[i]=0;
for (i=0;i<32;i++)
reg[i]=0;
IF_Time=0;
ID_Time=0;
EX_Time=0;
MEM_Time=0;
WB_Time=0;
//prompt input parameters===================================
printf("Memory access time: c=");
scanf("%d", &c);
printf("\nMultiply time: m=");
scanf("%d", &m);
printf("\nExecute time: n=");
scanf("%d", &n);
assert(c>0);
assert(m>0);
assert(n>0);
//start execution now that the program has been broken to unparsed strings====
while (0==0)
{
WB();
MEM();
if (MEM_WB.instruction.opcode==HALT)
break;
EX();
ID();
IF();
totalClock++;
system("PAUSE");
}
//PRINT RESULTS=============================================
printf("Run again with new parameters? 0=yes");
scanf("%d", &cont);
}
fclose(ifp);
system("PAUSE");
return 0;
}
struct inst parser(FILE *ifp){
char str[100];
struct inst temp;
if (fgets(str, 100, ifp)==NULL) {
inst temp={"NULL", -1,0,0,0};
}
else {
inst temp={str, 0,0,0,0};
puts(str);
}
return temp;
}
I am trying to read in a test file so that i can parse it into strings for analysis later. It opens the test file but it doesn't read the lines of test in the code. Is there something I am doing wrong.
Your parser functions only reads once from the file and does nothing with the result (since temp would be a local variable to the if branch, not to the function). First thing is to remove inst from inst temp = ... to see that it reads the first instruction. Then, you need to make that function loop over all lines in the file.
First of all, you need to format your source code on this page to make it more readable.
For parser(), I don't think you can return a structure. So please use a pointer instead. And, as Mihai mentions, "temp" is a temporary variable located on the stack, and it will be destroyed when returning from function parser().
I don't see the declarations of variables in the code snippet:
IF_Time=0;
ID_Time=0;
EX_Time=0;
MEM_Time=0;
WB_Time=0;
So I assume you could remove some unused code to make the question clear.
The last thing is: to analyze log files, shell scripts is more suitable than C. If you're not working on a UNIX/Linux box, you could also use Perl/Python if you want. They are all less error prone and easy to debug when used to analyze log files.

Resources