Segmentation fault SIGSEGV error on BeagleBone - c

I have still problem with a Segmentation fault in the C code. When I call the function current_live_read(ainpath); for the 8th time I'm getting the error: No source available for "_int_malloc() at 0x25be2"
The main function looks like this:
void current_read(void)
{
system(AINinit);
char *ainpath;
ainpath=init_current();
int *current;
float avgcurr=0;
float allcurr=0;
int i=0;
while(1)
{
//sleep(1);
i++;
current=current_live_read(ainpath);
allcurr=allcurr+*current;
avgcurr=allcurr/i;
printf("\n Current: %d AVG: %f", *current, avgcurr);
//free(current);
}
}
The current_live_read(ainpath); is like that:
int *current_live_read(char *ainpath)
{
//ainpath=init_current();
int curr;
FILE *file = fopen(ainpath, "r");
//free(ainpath);
if(!file)
{
printf("Error opening file: %s\n", strerror(errno));
}
else
{
fscanf(file, "%4d", curr);
fclose(file);
//*current=curr;
}
free(file);
return curr;
}
I know that something could be wrong with the pointers, but I don't know which one and what I can do about it.

You may not free the FILE * pointer after closing it. From the manpage:
Flushes a stream, and then closes the file associated with that stream. Afterwards, the function releases any buffers associated with the stream. To flush means that unwritten buffered data is written to the file, and unread buffered data is discarded.
So fclose() already does the cleaning up as needed to prevent a memory leak. If you call free() on that pointer, you are likely to corrupt your heap. So just remove the free(file);
Furthermore, you have to pass a pointer to fscanf() like this:
fscanf(file, "%4d", &curr);
Otherwise you write to a (pseudo)random memory address. It is usually a good idea to check the return value of fscanf() to see, if the conversion succeeded and handle the error case approriately.
This should eliminate the problem.

So I changed the int *current_live_read(char *ainpath); to int current_live_read(char *ainpath) without pointer type.
Make inside function:
int curr; fscanf(file, "%x", &curr)
And in main function the current is just integer:
int current;

Related

Assigning a value to an int variable causing segmentation fault in C

I am trying to write a function to read an input from a separate file in C, and arrange this data for further processing. I am, however, running into a segmentation fault when i am trying to assign values to int variables.
The code looks like this:
void read_file1 (char *filename, int *numTrees)
{
int tempNum;
char tempStr[1000];
char line;
FILE *filer;
filer = fopen(filename, "r");
fgets(tempStr, 1000, filer);
sscanf(tempStr, "numTrees: %i numLeaves: %i", numTrees, &tempNum);
/*
More Code
*/
}
void read_file2 (char *filename, int *numTrees, int *numLeaves)
{
char tempStr[1000];
char line;
FILE *filer;
filer = fopen(filename, "r");
fgets(tempStr, 1000, filer);
sscanf(tempStr, "numTrees: %i numLeaves: %i", numTrees, numLeaves); //Segmentation fault occurs here
/*
More Code
*/
}
int main()
{
char *filename = "datainput.txt";
int *numTrees, *numLeaves;
read_file2(filename, numTrees, numLeaves);
return 0;
}
The two different read_file functions are meant to arrange the data in different formats. The read_file1 functions works as intended, yet when i try to use a largely identical setup in read_file2, i get a segmentation fault from the sscanf. The problem seems to lie with the assignment of a value to numTrees, as attempting to assign a value separately also triggers a segmentation fault.
Which is strange, seeing as the nearly identical read_file1 works fine.
Can anyone tell the issue that is causing the error?
At least this is wrong in your code (a very common beginner's error):
int *numTrees, *numLeaves; // those pointers are not initialized
read_file2(filename, numTrees, numLeaves);
instead you want this:
int numTrees, numLeaves;
read_file2(filename, &numTrees, &numLeaves); // provide the pointers
// to the int variables
// numTrees and numLeaves
Also a check for fopen is mandatory:
filer = fopen(filename, "r");
if (filer == NULL)
{
printf("Fatal erorr, file does not exist\n");
exit(1);
}
This will abort program if the files not not exist. In real world programs a more sophisticated error handling should be done, but here at least we eliminate the chance of reading from an invalid FILE pointer.

Sending a string through a thread function to be opened with fopen()

I'm taking a string(char *) from a FIFO named pipe, from there I'm putting it in a thread. Once I pass the string(char *) to the thread function, I can print it out just fine. However, if I do
FILE *fp;
fp = fopen(string, "wb");
if(fp){
//it never reaches here
}
the entire function is basically as follows for the relevant parts.
void *threadFunction(void *stringBuf){
char *someString;
someString = (char *) stringBuf;
printf("%s\n", someString); //prints fine
FILE *fp;
fp = fopen(someString, "wb");
if (fp) {
//do stuff, but it never reaches here
}
What am I doing wrong here?
There is nothing obvious in the given code that is specifically thread related that would cause consistent failures.
How is stringBuf allocated in the calling thread? If it is on the stack it could be overwritten by the calling thread between the printf and the fopen, but you'd expect to see that as an intermittent failure.
Allocate the buffer with malloc() to eliminate this as a possibility.

I keep getting a segfault when trying to pass a struct node* and then print using printf

Full code here: https://gist.github.com/IamSlightly/5debd2373231a62c0a44665902e9ca7f
Not sure exactly why this is happening but it happens in line 43 when the printf tries to access the returned value.
struct node* kv = Lookup (13);
if (kv)
printf ("%s\n", kv->val_ptr);
struct node* Lookup(int x){
struct node *holder;
holder = head;
while ((holder->key!=x) && (holder->next!=NULL)){
holder = holder->next;
}
if (holder->key==x) {
printf("\nlets try this shit again\n");
return holder;
} else {
printf("\n*** %d is not in the linked_list ***\n", x);
return NULL;
}
}
If you're crashing on:
printf ("%s\n", kv->val_ptr);
then it's a safe bet that either kv or kv->val_ptr are not pointing to something that's "kosher".
Since your Lookup code seems to preclude returning an invalid pointer (assuming of course you haven't screwed up the creation of the linked list), it's likely that the val_ptr field hasn't been set correctly, or it's pointing at something that isn't a string.
Your best bet is to use a debugger (or printf lines if you don't have a decent one) and examine values before attempting to use them. That will greatly assist you in figuring out the root cause.
If you were to go the printf route (I'd prefer a debugger but it's not always an option), I would be looking at code like the following, place before your own if (kv) line:
if (kv) {
printf ("Starting DEBUG\n");
fflush (stdout); fsync (fileno (stdout));
printf ("kv as pointer is %p\n", kv);
fflush (stdout); fsync (fileno (stdout));
printf ("kv->val_ptr as pointer is %p\n", kv->val_ptr);
fflush (stdout); fsync (fileno (stdout));
printf ("kv->val_ptr as char[10] is %10.10s\n");
fflush (stdout); fsync (fileno (stdout));
printf ("Ending DEBUG\n");
fflush (stdout); fsync (fileno (stdout));
}
This shows how to write debugging statements in such a way that they'll be flushed before the core dump stops output.
Basically, what you need to do is to narrow down the issue gradually until you can isolate it to a specific line, then work out what's wrong with that line :-)
As an aside, if an empty list will consist of head being set to NULL, that Lookup code is going to crash on you. That's probably not the case here since you've stated it's the actual printf line which is crashing.
A better one would be something like:
struct node* Lookup (int x) {
struct node *holder = head;
while (holder != NULL)
if (holder->key == x)
return holder;
return NULL;
}
In addition, based on the code at the link you gave, you may want to add function prototypes to your header file. You have the structure and variables such as head but it's a good idea for any code using your implementation to have properly-defined definitions for the functions within it. As an example, it should contain something like:
int Insert(int, char*, int);
for the Insert function, ditto for the other functions you wish to call.

fopen() causing segfault before it's called

I am having a very weird error, I would try to run valgrind, but I am on OS X Yosemite, so this is not possible. I am getting a segfault with an fopen, it seems before the fopen is ever even called. I have a function called format:
void format(uint16_t sector_size, uint16_t cluster_size, uint16_t disk_size)
{
FILE *fp;
fp=fopen(diskName, "wb");
if(fp != NULL)
{
printf("Disk successfully initialized at: %s",diskName);
}
else
{
printf("There was an error creating the disk.");
return;
}
for(int i=0;i<disk_size;i++)
{
fwrite(0, sizeof(sector_size), cluster_size, fp);
}
}
Diskname is declared globally at the top of the file:
char diskName[32];
Here is my main:
int main(int argc, char *argv[]) {
strcpy(diskName, "test.bin");
printf("%s",diskName);
format(128, 8, 1000);
}
The weird part is that, this code segfaults before it ever prints the diskname:
Run Command: line 1: 16016 Segmentation fault: 11
I have no idea how this is possible, and I've tried a wide-array of solutions, but it all boils down to an error with fopen. When fopen is commented out the code runs. Any idea why this would happen?
printf will buffer its output until you flush the output. This can be done by either printing a newline, or flushing the output using fflush(stdout).
In any case, your error is here:
fwrite(0, sizeof(sector_size), cluster_size, fp);
You may not see your program crash when you comment out the fopen call because the fwrite call will fail earlier. fwrite's signature expects a pointer to the data to write as the first argument, where you have provided zero. This will cause fwrite to attempt to dereference a NULL pointer and thus crash.
You can either allocate a buffer, set it all to zero, then write that to the file using fwrite, e.g.
char* buf = calloc(cluster_size, sector_size); // Remember, calloc initialises all elements to zero!
fwrite(buf, sector_size, cluster_size, fp);
Or just call fputc in a loop
for(int i = 0; i < sector_size * cluster_size; i++)
fputc(0, fp);
Also, sizeof(sector_size) will always return 2 in your example, as you're taking the size of the type. Are you sure this is correct?

problems with the return value of fscanf in c

I'm sorry to do this kind of question (because there is so much on internet about that) but I have to ask this:
The exercise involve reading from a file with a list of students (a record contains: name, surname and serial number). I've already created the document and consist of 13 lines, but when I write on terminal ./a.out, the output is a list of 13 lines of this type: (null) (null) (null)
The code is:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define EOF (-1)
#define BUF 100
typedef struct stud{
char *surname;
char *name;
char *serial;
} student;
int main(void){
FILE *fd;
int n = BUF;
int k = 0;
int i = 0;
int ret;
char *s = malloc(BUF * sizeof(char));
if((fd = fopen("registry_office_students.txt","r")) == NULL){
perror("error opening file");
return -1;
}
while(fgets(s,n,fd)!=NULL){
k++;
}
student *a = malloc(k*sizeof(student));
rewind(fd);
ret = fscanf(fd, "%s, %s, %s", a[i].surname, a[i].name, a[i].serial);
while(fscanf(fd, "%s, %s, %s", a[i].surname, a[i].name, a[i].serial) == ret){
i++;
}
for(i=0;i<k;i++){
printf("%s, %s, %s \n", a[i].surname, a[i].name, a[i].serial);
}
fclose(fd);
return 0;
}
I apologize again and hope for a proper response, Thanks.
fscanf(3) with %s won't allocate any memory for a string. That string should already exist.
At least, replace
ret = fscanf(fd, "%s, %s, %s",
a[i].surname, a[i].name, a[i].serial);
with something like
{
char surname[48];
char name[64];
char serial[32];
memset (surname, 0, sizeof(surname));
memset (name, 0, sizeof(name));
memset (serial, 0, sizeof(serial));
memset (a+i, 0, sizeof(struct stud));
ret = fscanf(fd, "%47s, %63s, %31s", surname, name, serial);
if (ret==3) {
a[i].surname = strdup(surname);
if (!a[i].surname)
{ perror("strdup surname"); exit(EXIT_FAILURE); }
a[i].name = strdup(name);
if (!a[i].name)
{ perror("strdup name"); exit(EXIT_FAILURE); }
a[i].serial = strdup(serial);
if (!a[i].serial)
{ perror("strdup serial"); exit(EXIT_FAILURE); }
}
}
Notice that I am clearing memory before reading it. I am explicitly giving size of strings in format of fscanf. I am duplicating with a tested strdup the read strings into heap.
Actually, I believe your approach could be wrong. You might decide that each student should be on a single line, which you would read with getline(3) and parse with sscanf(3) (maybe %n would be useful!) or maybe strtok (or "manually" using isalpha)
Please, read more material about C programming, then compile with all warnings and debug info (gcc -Wall -g), learn to use the debugger (gdb) and the memory leak detector (valgrind).
Firstly, you never allocate memory for the strings stored inside your structs. I.e. your fscanf attempts to read data into buffers that don't exist.
Secondly, your reading code reads data into a[0] twice. I.e. the first fscanf will read the first record in a[0] and then the next fscanf will read the next record into a[0] again, overriding what was read previously. Why? Was that your intent (like skipping a table header or something like that)?
Thirdly, your counting code (fgets) is not the same as your reading code (fscanf). If the reading code fails prematurely for fscanf-specific reason, you will read less than k records. Yet your printing code prints all k of them unconditionally. (What if your reading code failed immediately due to some error in fscanf format? In that case you never read anything.)
Fourthly, each call to fgets in your counting code is limited by 100 characters or by a newline (that's how fgets works). This is completely non-synchronized with how fscanf works, which is not limited by anything in your case. This means that the number of records seen by the counting code might easily end up different (greater) than the number of records seen by the reading code.

Resources