I can't seem to find the cause of the segmentation fault in the code below. The code crashes in the line with the comment, after jumping back to main() from evaluate(). I looked at this code with gdb, and it seems everything is ok within the evaluate function - Output is filled in correctly, however after I return to main, nothing in the memory can be accessed. "p j" in gdb return an memory not accessible error, as does trying to print any other variable. I checked if the stack maybe had to many values, but increasing the stack size does not help.
The crazy thing is that I can solve this error, but I have no idea why it changes anything. If I add, anywhere in evaluate(), an int declaration (eg. int iAmNotUsedEver;) then the code suddenly doesn't cause a segmentation error and works perfectly in gdb.
Edit: Dynamically allocating node[116] in evaluate (int *node = malloc(116*sizeof(int));) also resolves the issue, but again I have no idea why?
Evaluate function: (I removed part of the code, otherwise it would be way too long)
void evaluate(int *parameter, int output[][16]) {
int node[116];
node[0] = 0;
output[0][0] = !node[0];
node[1] = parameter[0];
output[0][1] = !node[1];
output[0][2] = !node[0];
...
node[34] = !node[114] && !node[45];
node[45] = !node[34] && !node[105];
output[11][15] = node[45];
}
Main function:
int main(int argc, char *argv[]) {
int i;
int j;
int k;
int ret;
int parameter[8];
int output[12][16];
FILE *paramFile;
FILE *outFile;
paramFile = fopen(argv[1], "r");
if (paramFile == NULL) {
printf("I couldn't open the parameter file.\n");
exit(0);
}
outFile = fopen(argv[2], "ab");
if (outFile == NULL) {
printf("Something went wrong with the output file.\n");
exit(0);
}
while(1){
for(i=0;i<8;i++){
ret=fscanf(paramFile, "%d", ¶meter[i]);
printf("parameter: %d\n", parameter[i]);
}
if(ret!=1){
break;
}
for(j=0;j<12;j++){
for(k=0;k<16;k++){
output[j][k] = 2;
}
}
evaluate(parameter,output);
printf("Evaluation is done. \t %d\n",i);
for(j=0;j<12;j++){ //SEG FAULT HERE
for(k=0;k<16;k++){
fprintf(outFile, "%d", output[j][k]);
}
fprintf(outFile,"\n");
}
fprintf(outFile,"\n\n\n");
}
printf("Closing files\n");
fclose(paramFile);
fclose(outFile);
return 0;
}
First of all you should check if there is at least two argument. This can provoque a segmentation fault too.
if (argc < 3)
return -1;
Then, in evaluate, as they are fixe array you should pass in parameter
void evaluate(int parameter[8], int output[12][16]) {
...
}
You can also do this
void evaluate(int *parameter, int **output) {
...
}
I think the segfault can be avoid using one on this two declaration.
Related
I'm making a project for a class in C [ANSI-90]
for some reason, I get a stack smashing error, I know it's gcc protection for buffer overflow, or accessing a memory that shouldn't be accessed as far as I've understood.
but I can't find why.
i found out that it aborts once i return from a function that is supposed to parse only the first word of input into a command using strtok
this is what i got:
int getCommand(char *p, commands *cmd)
{
int i = 0;
char lineCopy[MAX_LINE_LEN];
char *cmdName;
strcpy(lineCopy, p);
cmdName = strtok(lineCopy, "\t \n");
if (cmdName != NULL)
{
while (cmd[i].func != NULL)
{
printf("%d",i);
if (strcmp(cmdName, cmd[i].name) == 0)
return i;
++i;
}
}
i=-1;
puts("return error"); /* Just to check I'm reaching here, and i do */
return i; /* ERROR */
}
input example to recreate:
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
i will be happy if you could point and explain what am i doing wrong?
As #Alexander pointed out, I didn't allocate memory for linecopy, fixed with:
char *lineCopy = malloc(strlen(p));
When i try run with the reviews.csv file the code gives segmention
fault don't know why!! Can someone HELP me with that... In
guião1v2.h only are the structs made for this. In the code i add
some comments for being much easier understand what i'm doing.
I don't know how to fix this!!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "guião1v2.h"
#define COUNT 1024
#define MAX_LINE 10000000 //random num (the files given are big)
int main(int arg , char*argv[]){
int i = 0;
char buffer[COUNT];
char *buffer2 = malloc(COUNT);
User *user = malloc(sizeof(User)*MAX_LINE);
Review *reviews = malloc(sizeof(Review)*MAX_LINE);
//i do the allocation of memory.
FILE *files;
files = fopen(argv[1],"r"); //opening the file
if(files == NULL)
{
printf("Failed to open file");//in case of fail to open the file
exit(1);
}
if(strcmp(argv[1], "reviews.csv") == 0)
{
while (fgets(buffer2,COUNT,files))//trying to pass from the file to the struct
{
reviews[i].id = strdup(strsep(&buffer2,";"));
reviews[i].user_id =strdup(strsep(&buffer2,";"));
reviews[i].business_id =srdup(strsep(buffer2,";"));
reviews[i].stars = atof(strsep(&buffer2,";"));
reviews[i].useful = atoi(strsep(&buffer2,";"));
reviews[i].funny = atoi(strsep(&buffer2,";"));
reviews[i++].cool = atoi(strsep(&buffer2,";"));
}
for(int j=0; j < i-1; j++)//testing if the data was well copied.
{
printf("%s", reviews[j].id); //param
printf("%s", reviews[j].user_id); //param
printf("%s", reviews[j].business_id); //param
printf("%f", reviews[j].stars); //param
printf("%d", reviews[j].useful); //param
printf("%d", reviews[j].funny);
printf("%d", reviews[j].cool);
printf("\n");
}
}
fclose(files); // When i don't need the file i close it
free(user);//I give free to the memory
free(reviews);// Same thing
free(buffer2);
return 0;
}
Segmentation faults occurs only incase there are some memory issues. The code above uses command line argument as well as dynamic allocation through malloc.
I suggest remove the command line arguments from main() to make the code looks simpler. The problem here related to memory so try to specify memory statically not dynamically using malloc(),calloc() etc.
I am doing an assignment for school and I keep getting my fopen function returning NULL. Please keep in mind that this write_info function was working perfectly before I was required to start using dynamic arrays instead of statically defined ones.
Here are my main declarations:
void main(void)
{
struct assignment *assi = NULL;
char choice;
int choice_check = TRUE;
int loop = TRUE, keep_loop = TRUE;
int nbr_asst = 0;
char asst_file[] = "C:\\Users\\Main\\Documents\\asst.txt";
int nbr_asstfile = 0;
Here is the function call:
write_info(asst_file, assi, nbr_asstfile);
And here is the actual function:
void write_info(char asst_file[], struct assignment *asst_data,
int nbr_asstfile)
{
FILE *fptr;
int count;
fptr = fopen(asst_file, "w");
if (fptr != NULL)
{
fwrite(&nbr_asstfile, sizeof(nbr_asstfile), 1, fptr);
for (count = 0; count < nbr_asstfile; count++)
{
fwrite(&asst_data[count], sizeof(asst_data[count]), 1, fptr);
}
fclose(fptr);
}
else
{
printf("Problem opening the file!");
}
return;
}
If I simply run the function after reading in from the text file, there is no problem to rewrite everything. However, if I add one entry to my structure, the fptr returns NULL when I try to write. Anybody know why?
I really hope I am asking this in a way that people can understand, and if you need any extra info please let me know. I didn't want to post the entire program because it is 505 lines.
Thank you to all in advance.
I'm writing a homework program in C. The program should take records from an input file and write those record to an output file. It seems like there is something wrong with the print_to_file function. I keep getting segmentation fault 11. Please help. My code is as below.
#include <stdio.h>
#include <stdlib.h>
typedef struct car { // create a struct type Car
char *license_plate;
int parking_spot;
int num_tickets;
int time_left;
} Car;
#define LICENSEPLATELENGTH 10
Car* import_cars(char *filename, int numCars);
void print_to_file(char* filename, Car* garage, int numCars);
int main(int argc, char * argv[]) {
if(argc != 4)
printf("Incorrect input.\n");
else {
int number = atoi(argv[1]);
Car* parked_car = (Car*)malloc(sizeof(Car) * number);
parked_car = import_cars(argv[2], number);
print_to_file(argv[3], parked_car, number);
free(parked_car);
}
return 0;
}
Car* import_cars(char* filename, int numCars)
{
Car* inCar = (Car*)malloc(sizeof(Car) * numCars);
inCar->license_plate = (char*)malloc(sizeof(char) * 8);
//Question: How do I do if I the plate length is varied. How to malloc space to it?
FILE* inFilePtr;
if((inFilePtr = fopen(filename, "r")) == NULL)
printf("Error! Unable to open file %s. Check again.\n", *filename);
else
{
int i = 0;
fscanf(inFilePtr, "%s", inCar[i].license_plate);
fscanf(inFilePtr, "%d%d%d", inCar[i].parking_spot, inCar[i].num_tickets, inCar[i].time_left);
printf("%s %d %d %d \n", inCar[i].license_plate, inCar[i].parking_spot, inCar[i].num_tickets, inCar[i].time_left);
for(i = 1; i < numCars; i++)
{
fscanf(inFilePtr, "%s", inCar[i].license_plate);
fscanf(inFilePtr, "%d%d%d", inCar[i].parking_spot, inCar[i].num_tickets, inCar[i].time_left);
printf("%s %d %d %d \n", inCar[i].license_plate, inCar[i].parking_spot, inCar[i].num_tickets, inCar[i].time_left);
}
}
fclose(inFilePtr);
return(inCar);
//free(inCar.license_plate); `
//Question: Do I need to free space here would it remove the value
//stored in the variable which passed to main?
}
void print_to_file(char* filename, Car* garage, int numCars) {
FILE* outFilePtr;
if((outFilePtr = fopen(filename, "w+")) == NULL){
printf("Error! Cannot Open File %s!", *filename);
printf("here\n");
} else {
int i = 0;
for(i = 0; i < numCars; i++) {
printf("%s\n%d %d %d\n", garage[i].license_plate, garage[i].parking_spot, garage[i].num_tickets, garage[i].time_left);
fprintf(outFilePtr, "%s\n%d %d %d\n", garage[i].license_plate, garage[i].parking_spot, garage[i].num_tickets, garage[i].time_left);
}
}
fclose(outFilePtr);
}
This is my input command.
./a.out 6 garage.txt output.txt
Here is what print in my terminal.
fi590dz 20 2 25
57fjgmc 8 0 55
7dkgjgu 25 1 15
f9e829d 1 2 60
4jgfd81 12 2 10
Segmentation fault: 11
By the way, I'm pretty new in programming and really bad with debugging. Could you give me some tips of how to debug or any debugging tools? I use a mac so gdb doesn't work.
Not a complete answer, because it’s a homework problem and you want to figure it out yourself, but here are some hints.
First, you really want to learn how to run your program in a debugger and get it to tell you which line crashed the program, and on which data.
Second, make sure you initialize the pointers for every element of the array before you try to read or write them.
Third, you’ll save yourself a lot of trouble if you initialize all your dynamic and local variables to zeroes, not garbage. It will make a lot of bugs reproducible, make a lot of bugs crash immediately instead of corrupting memory, and also make it obvious when you debug that you’re using uninitialized data.
Therefore, I suggest you get in the habit of allocating your dynamic arrays with calloc(), not malloc().
The problem lies within your parked_car = import_cars(argv[2], number); and Car* import_cars(char* filename, int numCars);functions.
Indeed in Car* import_cars(char* filename, int numCars); you are doing this:
Car inCar;
inCar.license_plate = (char*)malloc(sizeof(char) * 8);
So you are creating a local variable that is not accessible outside of the function (many different things can happen to the memory after the end of the function).
So when you do: parked_car = import_cars(argv[2], number); you are assigning to parked_car a freed variable.
A solution is to simply use the parked_caras an argument of your import_cars() function. All modifications made within the function will still be valid after it returns. So you should have:
void import_cars(char* filename, int numCars, Car* car);
For everyone who met the issue here, I found the problem in my program. The problem is that I didn't allocate space for each of the license_plate pointer in the structure. So my way to solve it is add a line as below in the for loop of the import_cars function.
inCar[i].license_plate = (char*)malloc(sizeof(char) * LICENSEPLATELENGTH);
I'm building a user defined shell. I have an array of pointers to functions -- that is, an array full of shared library functions that can be invoked at any point.
I typedef here
typedef void (*func_ptr)(char **);
func_ptr function;
void *pointers_to_functions[64];
I have debugged and confirmed that my initializations of placing the pointers into the array is working properly, but here's the code for safe measures...
void initialize_built_in(){
void *handle;
char *error;
int i;
for (i = 0; i < 5; i++){
handle = dlopen(builtin_files[i], RTLD_LOCAL | RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
pointers_to_functions[i] = dlsym(handle, builtin_functions[i]);
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%c\n", *error);
exit(1);
}
if (dlclose(handle) < 0) {
fprintf(stderr, "%c\n", *dlerror());
exit(1);
}
}
}
Here's where the seg fault occurs -- when I invoke the function
int execute_built_in(char **argv){
int i;
//scan through the builtin_functions strings to find the correct index of pointers_to_functions - that is, they have the same ordering
for (i = 0; i < sizeof(builtin_functions); i++){
if (!strcmp(argv[0], builtin_functions[i])){
//the index has been found
function = pointers_to_functions[i];
function(argv); //execute function
return 0;
}
}
return -1;
}
My shared library does indeed take argv as a parameter -- so I don't believe this is the problem.
As I said, debugging I see that the array of pointers is filled with addresses. I suppose it could be an incorrect address somehow, but I'm at a brick wall here.
Any ideas?
So I tested the pointer to function call be defining my own function type (void *) in the same file.
func_ptr function;
void *testfunction(char **);
void *pointers_to_functions[64] = {testfunction};
where the function just prints something out to the shell
then I added a condition in the execute_function function to force execution...
for (i = 0; i < sizeof(builtin_functions); i++){
if (i == 0){
function = pointers_to_functions[1];
char *bleh[] = {"bleh"};
function(bleh);
}
if (!strcmp(argv[0], builtin_functions[i])){
//the index has been found
function = pointers_to_functions[i];
function(argv); //execute function
return 0;
}
}
and it works WOOHOO!
So I either have a problem with my dynamic linking, which I can't see. Or with my shared library -- which is unlikely because I've already built successful libraries that work with another shell code of the same project.
So, what's wrong with my dynamic linking?
Here's an example shared library
#include <stdio.h>
#include <unistd.h>
struct NewBuiltIn{
char *CommandName[64];
char *FunctionName[64];
char *AnalyzerName[64];
};
struct NewBuiltIn pluggin_method = {{"cd", "cd", ""}};
void cd(char *argv[]) {
if(chdir(argv[1]) < 0){
printf("There was an error in changing your directory. Please check the path name and retry.\n");
}
}
Your init function is wrong:
you perform a dlclose(handle) which causes all the lib you loaded to be unmapped from memory, and obviously, the functions you expect to call are flying away.
You must keep the lib mapped to memory until you completely finished using the function pointers you stored.
You can probably check this by observing that the address that segfaults actually lies in the library mapped segment (in /proc/your_app_pid/maps)