I have run into a problem when trying to write to file using fprintf(). When I start writing into file the first few lines are composed of semi-random invalid characters and after that the rest is printed normally. I have no idea what can cause the problem. Below is the code that produces the problem.
functions called:
double calc_time(clock_t s, clock_t e){
return ((double)(e-s) / (sysconf(_SC_CLK_TCK)));
}
void print_times(FILE *f, char *operation, clock_t s, clock_t e, struct tms *st, struct tms *et){
printf("%s", operation);
printf("\nREAL TIME: %f\n", calc_time(s,e));
printf("USER TIME: %f\n", calc_time(st->tms_utime,et->tms_utime));
printf("SYS TIME: %f\n", calc_time(st->tms_stime,et->tms_stime));
printf("HERE");
fprintf(f,"%s", operation);
fprintf(f,"\nREAL TIME: %fl", calc_time(s,e));
fprintf(f,"\nUSER TIME: %fl", calc_time(st->tms_utime,et->tms_utime));
fprintf(f,"\nSYS TIME: %fl", calc_time(st->tms_stime,et->tms_stime));
}
and the printing takes place here:
f = fopen("raport2.txt","a");
clock_t r_times[2];
struct tms* t_times[2];
t_times[0] = calloc(1,sizeof(struct tms));
t_times[1] = calloc(1,sizeof(struct tms));
r_times[0] = times(t_times[0]);
struct block_array* array = create(4);
r_times[1] = times(t_times[1]);
print_times(f, "\nCreating array", r_times[0], r_times[1], t_times[0], t_times[1]);
r_times[0] = times(t_times[0]);
struct file_sequence seq = seq_def("t1.txt t2.txt b1.txt b2.txt");
char *tmp = compare(seq);
create_blocks(array,tmp,4);
r_times[1] = times(t_times[1]);
print_times(f,"\nCreating blocks",r_times[0],r_times[1],t_times[0],t_times[1]);
r_times[0] = times(t_times[0]);
delete_block(array,1);
delete_block(array,2);
delete_block(array,3);
delete_block(array,4);
r_times[1] = times(t_times[1]);
print_times(f, "\nDeleting blocks", r_times[0], r_times[1], t_times[0], t_times[1]);
The error was caused by a different part of code than provided in the snippets (although the github source will still reproduce it). It turns out that in a different part of program I was writing to a file without erasing it's previous contents (I thought that touch does that), then data retrieved from the file was causing memory leaks and all kinds allocation problems.
Use %lf to print doubles, rather than the typo %fl you're using.
Related
I am trying to make a c-program that will will a string, but I want it only to read a very small part of it.
The NMEA-telegram that I try to read is $WIXDR, and do receive the necessary strings.
Here's 2 examples of strings that I get into the CPU:
$WIXDR,C,1.9,C,0,H,83.2,P,0,P,1023.9,H,0*46
$WIXDR,V,0.01,M,0,Z,10,s,0,R,0.8,M,0,V,0.0,M,1,Z,0,s,1,R,0.0,M,1,R,89.9,M,2,R,0.0,M,3*60
If it were only 1 string (not both C and V), this would not be a problem for me.
The problem here is that it's 2 seperate strings. One with the temperature, and one with rain-info.
The only thing that I'm interested in is the value "1.9" from
$WIXDR,C,1.9,C,0......
Here's what I have so far:
void ProcessXDR(char* buffPtr)
{
char valueBuff[10];
int result, x;
float OutSideTemp;
USHORT uOutSideTemp;
// char charTemperature, charRain
IODBerr eCode;
//Outside Temperature
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
sscanf(&valueBuff[0],"%f",&OutSideTemp);
OutSideTemp *= 10;
uOutSideTemp = (USHORT)OutSideTemp;
eCode = IODBWrite(ANALOG_IN,REG_COM_XDR,1,&uOutSideTemp,NULL);
}
// XDR ...
if(!strcmp(&nmeaHeader[0],"$WIXDR"))
{
if(PrintoutEnable)printf("XDR\n");
ProcessXDR(buffPtr);
Timer[TIMER_XDR] = 1200; // Update every minute
ComStateXDR = 1;
eCode = IODBWrite(DISCRETE_IN,REG_COM_STATE_XDR,1,&ComStateXDR,NULL);
}
There's more, but this is the main part that I have.
I have found the answer to my own question. The code that would do as I intented is as follows:
What my little code does, is to look for the letter C, and if the C is found, it will take the value after it and put it into "OutSideTemp". The reason I had to look for C is that there is also a similar string received with the letter V (Rain).
If someone have any input in a way it could be better, I don't mind, but this little piece here does what I need it to do.
Here's to example telegrams I receive (I wanted the value 3.0 to be put into "OutSideTemp"):
$WIXDR,C,3.0,C,0,H,59.2,P,0,P,1026.9,H,04F
$WIXDR,V,0.00,M,0,Z,0,s,0,R,0.0,M,0,V,0.0,M,1,Z,0,s,1,R,0.0,M,1,R,89.9,M,2,R,0.0,M,358
void ProcessXDR(char* buffPtr)
{
char valueBuff[10];
int result, x;
float OutSideTemp;
USHORT uOutSideTemp;
// char charTemperature, charRain
IODBerr eCode;
// Look for "C"
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
// sscanf(&valueBuff[0],"%f",&charTemperature);
if (valueBuff[0] == 'C')
//Outside Temperature
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
sscanf(&valueBuff[0],"%f",&OutSideTemp);
OutSideTemp *= 10;
uOutSideTemp = (USHORT)OutSideTemp;
eCode = IODBWrite(ANALOG_IN,REG_COM_XDR,1,&uOutSideTemp,NULL);
}
A segmentation fault occurs when I want to access or modify the value of a struct member in C programming language.
I actually write a battleship networked game in C language (it is a student project). I have a structure named Player:
enum state{PLAYING = 0, WINNER = 1, LOOSER = 2};
enum action{ATTACK = 1, WAIT = 0, NOTHING = -1};
typedef struct Player Player;
struct Player
{
enum action action;
enum state state;
char name[25];
int isFirstPlayer;
Client* client;
Server* server;
Boards* boards;
};
the main function.
int main(int argc, char *argv[])
{
if(argc < 2)
{
errorUsage();
}
// Initialise player
Player player = newPlayer();
// I removed the network initialization here.
// play game
play_game(&player);
}
the segmentation fault occurs in the function play_game(Player* p):
void attack(Player* p)
{
char msg[2];
bzero(msg, strlen(msg));
printf("Where do you want to fire?");
scanf("%s", msg);
while(verifyEntryAttack(msg) != 1)
{
printf("ERROR Entry:\nFormat = A4, C9, ...\nColumns = A B C D E F G H I J\nRows = 0 1 2 3 4 5 6 7 8 9\n");
printf("please try again: ");
scanf("%s", msg);
}
sendData(p, msg);
Box my_attack_box;
my_attack_box.abs = msg[0];
my_attack_box.ord = msg[1]-'0';
updateMarkBoard(p, my_attack_box);
}
void receiveAttack(Player* p)
{
char received_attack[2];
receiveData(p, received_attack);
printf("I have received the attack: %s\n", received_attack);
Box my_attack_box;
my_attack_box.abs = received_attack[0];
my_attack_box.ord = received_attack[1]-'0';
endureAttack(my_attack_box, p);
}
void play_game(Player* p)
{
while(p->state == PLAYING){
printPlayer(p); //print the game boards.
if(p->action == ATTACK){
printf("Your turn to attack.\n");
attack(p); //attack the ennemy
printf("end of attack turn.\n");
} else if(p->action == WAIT){
printf("wait for an attack...\n");
receiveAttack(p); //receive the attack from the ennemy.
printf("end of waiting turn.\n");
}
if(p->action == WAIT){
p->action = ATTACK;
}
else{
p->action = WAIT;
}
}
}
After one turn in the while loop, the program says "segmentation fault". My tests show that is the p->action which is the problem.
See below the program output that shows the problem: outputs screenshot.
The entire code is available here: GitLab repo link.
It's like my program can't access the action member of my player.
Does anyone have any ideas?
char msg[2];
bzero(msg, strlen(msg));
Okay, so here you try to calculate the length of an uninitialized string, a typical source of page faults (and kernel vulnerabilities). strlen does not know your array's size, it simply looks for a zero character and is likely to get out of your page very soon. Even if the program does not crash at this point, bzero will do the trick as it is likely to write memory out of your reach.
Note that a cell is usually described with at least two characters ("C4" or so), so scanf will write the terminating zero character past the end of msg (again, this could be even out of your available memory). Increase msg's size so that it can accommodate at least valid inputs (at least three chars, the more the better). And you don't need to call strlen here; if you want to pre-clear your array, the simplest way would be to initialize it properly: char msg[256] = {'\0'};.
Next, you haven't shown your NewPlayer()'s code, but your struct contains three pointer fields, please double-check they are allocated, and initialized, properly.
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.
Original code comment specifying the core question:
The error I am getting is while iterating through the while loop,
memory out of range or something... resizing to 300 ... Access
violation writing location that's the exact Fraze...
I'm trying to implement a faster .Net List<T> equivalent in C.
I'm using blittable data types in C#.
In the code below I've moved a function body to the main function just for testing after I have failed to understand where am I wrong.
The problem seems to be that inside the while loop UntArr does not increment.
What am I doing wrong?
typedef struct {
int Id;
char *StrVal;
}Unit; // a data unit as element of an array
unsigned int startTimer(unsigned int start);
unsigned int stopTimer(unsigned int start);
int main(){
Unit *UntArr= {NULL};
//Unit test[30000];
//decelerations comes first..
char *dummyStringDataObject;
int adummyNum,requestedMasterArrLength,requestedStringSize,MasterDataArrObjectMemorySize,elmsz;
int TestsTotalRounds, TestRoundsCounter,ccountr;
unsigned int start, stop, mar;
//Data Settings (manually for now)
requestedMasterArrLength=300;
requestedStringSize = 15;
//timings
start=0;stop=0;
//data sizes varies (x86/x64) compilation according to fastest results
MasterDataArrObjectMemorySize = sizeof(UntArr);
elmsz= sizeof(UntArr[0]);
TestRoundsCounter=-1;
start = startTimer(start);
while(++TestRoundsCounter<requestedMasterArrLength){
int count;
count=-1;
//allocate memory for the "Master Arr"
UntArr = (Unit *)malloc(sizeof(Unit)*requestedMasterArrLength);
dummyStringDataObject = (char*)malloc(sizeof(char)*requestedStringSize);
dummyStringDataObject = "abcdefgHijkLmNo";
while (++count<requestedMasterArrLength)
{
dummyStringDataObject[requestedStringSize-1]=count+'0';
puts(dummyStringDataObject);
ccountr=-1;
// tried
UntArr[count].Id = count;
UntArr[count].StrVal = (char*)malloc(sizeof(char)*requestedStringSize);
UntArr[count].StrVal = dummyStringDataObject;// as a whole
//while(++ccountr<15)// one by one cause a whole won't work ?
//UntArr[count].StrVal[ccountr] = dummyStringDataObject[ccountr];
}
free(UntArr);free(dummyStringDataObject);
}
stop = startTimer(start);
mar = stop - start;
MasterDataArrObjectMemorySize = sizeof(UntArr)/1024;
printf("Time taken in millisecond: %d ( %d sec)\r\n size: %d kb\r\n", mar,(mar/1000),MasterDataArrObjectMemorySize);
printf("UntArr.StrVal: %s",UntArr[7].StrVal);
getchar();
return 0;
}
unsigned int startTimer(unsigned int start){
start = clock();
return start;
}
unsigned int stopTimer(unsigned int start){
start = clock()-start;
return start;
}
testing the code one by one instead of within a while loop work as expected
//allocate memory for the "Master Arr"
UntArr = (Unit *)malloc(sizeof(Unit)*requestedMasterArrLength);
UntArr[0].Id = 0;
dummyStringDataObject = (char*)malloc(sizeof(char)*requestedStringSize);
dummyStringDataObject = "abcdefgHijkLmNo";
////allocate memory for the string object
UntArr[0].StrVal = (char*)malloc(sizeof(char)*requestedStringSize);
////test string manipulation
adummyNum=5;
UntArr[0].StrVal= dummyStringDataObject;
//
UntArr[0].StrVal[14] = adummyNum+'0';
////test is fine
as it happens and as i am new to pointers i have not realize that when debugging
i will not see the elements of given pointer to an array as i am used to
with normal Array[] but looping through result which i did not even try as when i was hovering above the Array* within the while loop expecting to see the elements as in a normal array:
Data[] DataArr = new Data[1000] <- i have expected to actually see the body of the array while looping and populating the Data* and did not realize it is not an actual array but a pointer to one so you can not see the elements/body.
the solution is via a function now as planed originally :
void dodata(int requestedMasterArrLength,int requestedStringSize){
int ccountr,count;
count=0;
UntArr=NULL;
UntArr = (Unit *)malloc(sizeof(Unit)*requestedMasterArrLength);
while(count!=requestedMasterArrLength)
{
char dummyStringDataObject[]= "abcdefgHi";
UntArr[count].StrVal=NULL;
dummyStringDataObject[requestedStringSize-1] = count+'0';
UntArr[count].Id= count;
ccountr=0;
UntArr[count].StrVal= (char*)malloc(sizeof(char)*requestedStringSize);
while(ccountr!=requestedStringSize){
UntArr[count].StrVal[ccountr] = dummyStringDataObject[ccountr];
++ccountr;
}
++count;
}
}
generaly speaking, x86 compilation would get better performance for this current task , populating an array of a struct.
so i have compiled it also in c++ and c#.
executing similar code in C# and C++
minimum time measured in c# ~ 3,100 ms.
minimum time measured in this code - C ~ 1700 ms.
minimum time measured in C++ ~ 900 ms.
i was surprised to see this last result c++ is the winner but why.
i thought c is closer to the system level, CPU, Memory...
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.