segmentation fault only using valgrind - c

I'm programming a spellchecker for an class assignment. The first step is to load a list separated by "\n" in a "dict" (that actually is a char** dict_main).
The procedure to load the dict is the next:
void dict_load(char *fname){
FILE *loaded_file = fopen(fname, "r");
char **aux = NULL;
int a = 0;
char word[MAX_WORD_SIZE];
//Checks whether fname was successfully loaded or not
if(loaded_file == NULL){
perror("Could not load dict\n");
exit(1);
} else {
while(fgets(word, MAX_WORD_SIZE, loaded_file) != NULL){
main_size++;
while(aux == NULL){
//To ensure that aux is not NULL
aux = realloc(dict_main, main_size);
}
dict_main = aux;
aux = NULL;
//Allocs space enough to store word
dict_main[main_size-1] = calloc(MAX_WORD_SIZE, sizeof(char));
strcpy(dict_main[main_size-1], word);
}
}
//Just for debbuging, prints each string in dict_main
for(a = 0; a<main_size; a++){
fprintf(stdout, "%s", dict_main[a]);
}
fclose(loaded_file);
}
This seems to work when I run it normaly, but when I use valgrind, I get a segfault when it tries to printf the strings.
This is the only procedure that runs in the program, this is main:
int main(int argc, char **argv){
char *dict;
//int i;
if (argc < 2)
{
printf("spellchecker.c: nro de argumentos erroneo. Deben ser <documento> [<diccionario>].\n");
return (1);
}
dict = (argc >=3) ? argv[2] : "dict.txt";
dict_main = calloc(main_size, sizeof(char*));
dict_load(dict);
free(dict_main);
printf("El documento %s ha sido procesado. Resultados en out.txt\n", argv[1]);
Is there something I'm missing and gets me that SegFault when I run it with valgrind?
}

Related

Why my program crashes when I declare this two variables?

I'm trying to make an interpreter using C programming language, it works well, but when I try to add these two variables in the code, the program just crashes.
Fortunately, when I add the static keyword or I leave the variables as global in the program, the program doesn't crash.
Why does this happen ?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
//If I leave the variables here the program doesn't crash
//int esMain = 0;
//int esEnd = 0;
int main(int argc, char** argv){
FILE *f;
f = fopen(argv[1], "r+");
if(f == NULL){
perror("Error: No se encuentra el archivo\nDescripcion");
exit(1);
}
if(ferror(f)){
printf("Archivo corrupto");
exit(1);
}
printf("\nEjecutando archivo: %s\n\n\n", argv[1]);
int esMain = 0;//These two variables makes the program to crash
int esEnd = 0;
//But if I add the static keyword in both variables the program works well.
char* str;
while(1){
fgets(str, 25, f);
if(strncmp(str, "MAIN:", 5) == 0){
esMain = 1;
}
if(strncmp(str, "END.", 4) == 0){
esEnd = 1;
}
if(feof(f) != 0){
if(esMain == 0){
printf("No existe el parametro main, cierre por no tener el parametro main (poner MAIN: ENCIMA)");
exit(1);
}
if(esEnd == 0){
printf("No existe el parametro end, cierre por no tener el parametro main (poner END. ENCIMA)");
exit(1);
}
break;
}
}
rewind(f);
while(1){
fgets(str, 500, f);
if(strncmp(str, "print ", 6) == 0){
printf(str + 6);
}
if(strncmp(str, "msg", 3) == 0){
if(strstr(str + 4, "check")){
MessageBox(HWND_DESKTOP, str + 10, "Check", MB_ICONINFORMATION);
}
if(strstr(str + 4, "error")){
MessageBox(HWND_DESKTOP, str + 10, "Error", MB_ICONERROR);
}
}
if(strncmp(str, "pause", 5) == 0){
getch();
}
if(feof(f) != 0){
break;
}
}
printf("\n\n\nEND EXECUTION");
fclose(f);
return 0;
}
The char* str; declaration is probably what is breaking your code. When you declare it as global it is stored in a different place in memory than if you declare it inside a function.
You got lucky to have your program working with it as global variable. Since you haven't reserved any place in memory, the variable is accessing some memory that it shouldn't (undefined behavior). Lucky might not be the best word to describe because due to t his undefined behavior you might think that your program is working correctly, which is not (If it had crashed you would be 100% that there were errors).
What you can do to fix that is one of the following:
allocate it dynamically: char *str = (char*)malloc(sizeof(char)*25);
change it to br an array: char str[25];
point to an existing array: char arr[25]; char *str = arr;

Seg Fault when working with strings C Program / Popen

I have looked for an answer to my question for almost two days and tried every solution suggested to no avail.
I am trying to access a file through a linux terminal using my C Program.
I want to run popen() to do this.
The command I want to run in popen() is : grep -o %s /usr/share/dict/words
Where %s is a variable word that changes each iteration. I have tried using pointers, arrays, and alternative functions such as asprintf() / snprintf()
Here is the code I have right now:
char *message = (char *)malloc(500);
strcpy(message, "grep -n");
printf("%s", message);
strcat(message, "hello");
printf("%s", message);
strcat(message, " /usr/share/dict/words"); // SEG FAULT OCCURS HERE
printf("%s", message);
I would then pass this to popen.
I have also tried initializing as: char message[500] and this returns the same error in the same spot.
Here is my full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "caeserheader.h"
int main( int argc, char *argv[]){
char *inputfile;
int n = 0;
int shiftamount = 0;
//Determine amount of arguments
if(argc == 2){
inputfile = argv[1];
}
else if(argc == 3){
inputfile = argv[1];
n = atoi(argv[2]);
shiftamount = n * (-1) ;
}
else{
printf("Please enter a proper number of arguments.");
return -1;
}
//OPENS INPUT FILE
FILE *input = fopen(inputfile, "r");
if(input == NULL){
printf("\n FILE NOT FOUND.");
perror("fopen");
return -1;
}
//RESERVES MEMORY AND GRABS STRING
fseek(input, 0L, SEEK_END);
long Tsize = ftell(input);
rewind(input);
char *inputtext;
inputtext = calloc( 1, Tsize+1);
//ERROR CHECKING
if(!inputtext){
fclose(input), printf("MEMORY FAILED.");
}
if(1!=fread( inputtext, Tsize, 1, input)){
fclose(input), free(inputtext), printf("READ FAIL.");
}
//CREATES DECRYPTED STRING
char newletter;
char *newstring;
int i;
//WITH GIVEN NUMBER OF SHIFTS
if(argc == 3){
newstring = malloc(Tsize + 1);
for(i=0; i<Tsize; i++){
newletter = shift(inputtext[i], shiftamount);
newstring[i] = newletter;
}
}
//WITHOUT GIVEN NUMBER OF SHIFTS
if(argc == 2){
char *message = (char *)malloc(500); //SEG FAULT SOMEWHERE HERE?
// strcpy(message, "grep -n");
// printf("%s", message);
//strcat(message, "hello");
// printf("%s", message);
// strcat(message, "/usr/share/dict/words");
//printf("%s", message);
// word = strtok(inputtext," ,.-!?\n");
// int i;
//for(i=0; i<10; i++){
//word = strtok(NULL," ,.-!?\n");
//printf("\n%s", word);
//}
// if(( fp = popen(message, "r")) == NULL){
//perror("No file stream found.");
//return -1;
// }
// else {
// pclose(fp);
// printf("FOUND.");
// }
}
// PUTS DECRYPTED STRING IN NEW FILE
char copiedname[100];
strcpy(copiedname, inputfile);
strcat(copiedname, ".dec");
FILE *newfile = fopen(copiedname, "w");
fputs(newstring, newfile);
// free(newstring);
fclose(input);
fclose(newfile);
return 0;
}
You have set inputfile to argv[1] and later you have used strcat to append to it. Don't do this. You don't own argv.
The strcat function appends a copy of the source string to the destination string, and then returns a pointer to the destination string. It does not "add two strings and return the result" which is how you seem to be using it.

read line from file and store each word into an array (C language)

I'm trying to make a function in C that reads a first line form file and store each word into an array of strings, than return the array or print it (I used strtok()). I've written my code but when I test it I get an error: "segmentation error" which I don't know what it means.
any help??? I saw this question Segmentation fault with array of strings C
i think it's similar but I still don't understand.
Here's my code :
the function that reads data from file and store it into an array
function is on the file: methodes.c
void lireFichier (char *file)
{
int i = 0;
int nbElement = 4;
char ** tab;
char line [1000];
char *str[1000];
const char s[2] = " ";
char *token;
FILE *myFile;
myFile = fopen(file, "r");
if(!myFile)
{
printf("could not open file");
} else
{
printf("file opened\n");
//while(fgets(line,sizeof line,myFile)!= NULL)
//get the fisrt line
fgets(line,sizeof line,myFile);
//fprintf(stdout,"%s",line);
//get the fisrt word
token = strtok(line, s);
for(i =0; (i< nbElement) && (token != NULL); i++)
{
int len = strlen(token);
tab[i] = malloc(len);
strncpy(tab[i], token, len-1);
token = strtok(NULL, s);
//printf( "%s\n", tab[i]);
}
}
fclose(myFile);
}
and here's the main.c
// I pass the file as argument (in argv)
#include <stdio.h>
#include <stdlib.h>
#include "methodes.h"
int main(int argc, char *argv[])
{
int result = 1;
if(argc < 2)
{
printf("Erreur dans les arguments\n");
} else
{
int idx;
for (idx = 0; idx < argc; idx++)
{
printf("parameter %d value is %s\n", idx, argv[idx]);
}
lireFichier(argv[1]);
}
return 0;
}
and here's an example of the file : methodes.txt
afficher tableau
partager elements roles
nommer type profession
fin
and this is my output:
file opened
Erreur de segmentation
note: the output is in french, so the message means segmentation error
thank you and sorry for all the details, i just wanted to make sure that people understand what i mean.
char ** tab;
Is a uninitialised pointer to a pointer. What you need is a array of pointers.
char *tab[10];
Instead of 10, use the size you see fit and adjust your code to include bounds checking.
http://www.tutorialspoint.com/cprogramming/c_array_of_pointers.htm
pointer of an array:
int *ptr[MAX];

c program is compiling and running but I am getting a weird output in the terminal

so I have a method that moves a string from a file to a char array in c, but when I try to print it out I am getting a weird output in the terminal that looks like a bunch of for each char spot and each box has 4 0's and 1's.
Here's the my code:
int main(int argc, char** argv){
if(argc != 3){
printf("not valid # of arguments");
return 1;
}
struct stat info;
int status;
status = stat(argv[2], &info);
if(status != 0){
printf("Error, errno = %d\n", errno);
return 1;
}
//command line argument is file
if(S_ISREG (info.st_mode)){
printf("%s is a file \n", argv[2]);
char *string1;
string1 = getFileString(argv[2]);
printf("string in file is %s \n", string1);
free(string1);
return 0;
}
if(S_ISDIR(info.st_mode)){
printf("%s is a directory \n", argv[2]);
openDirRec(argv[2]);
//what to do if command line argument is directory
}
return 0;
}
char* getFileString(char *fileName){
FILE* qp;
qp = fopen(fileName, "r");
char ch;
struct stat st;
if(stat(fileName, &st) != 0) {
return NULL;
}
/*int sizeCheck = 0;
while((ch=fgetc(qp))!=EOF){
sizeCheck++;
}
*/
int sizeCheck = st.st_size;
if(sizeCheck == 0){
return NULL;
}
else{
//fseek(qp, SEEK_SET, 0);
char *fileString;
fileString = (char*)malloc(sizeof(char) * sizeCheck + 1);
memset(fileString, 0, sizeCheck + 1);
//rewind(qp);
int count = 0;
while((ch=fgetc(qp)!=EOF)){
fileString[count] = ch;
count++;
}
printf("%s\n", fileString);
fileString[sizeCheck] = '\0';
fclose(qp);
return fileString;
}
}
This line is the culprit.
while((ch=fgetc(qp)!=EOF))
Due to operator precedence, that is equivalent to:
while(ch = (fgetc(qp)!=EOF) )
what you need is a little rearrangement of the parantheses.
while((ch=fgetc(qp)) != EOF)

memory in c programming

Hi i try to read a tkt input file to use it in my structure and it works fine but when i try to read the value image or adresse or nom it's empty
someone have any idea?
this is the code :
int nombre_radio(char* fichier_radio)
{
FILE* fichier = NULL;
char buf[TAILLE_MAX_RADIO]="";
int i;
fichier = fopen(fichier_radio, "r");
if (fichier != NULL)
{
i=0;
while (fgets(buf, TAILLE_MAX_RADIO, fichier) != NULL)
{
i++;
}
}
fclose(fichier);
return(i);
}
/* fonction pour récuperer l'image*/
void get_radio(int numero, char* fichier_radio, char* nom, char* adresse, char* image)
{
FILE* fichier = NULL;
char chaine[TAILLE_MAX_RADIO];
int i;
char im_temp[102400];
fichier = fopen(fichier_radio, "r");
if (fichier != NULL)
{
i=0;
while (fgets(chaine, TAILLE_MAX_RADIO, fichier) != NULL && i<numero){i++;}
strcpy(nom, strtok(chaine, "\t"));
strcpy(adresse, strtok(NULL, "\t"));
strcpy(im_temp, strtok(NULL, "\t"));
if (strstr(im_temp, "\n") != NULL)
strncpy(image, im_temp, strlen(im_temp)-1);
else
strncpy(image, im_temp, strlen(im_temp));
}
fclose(fichier);
return;
}
this is the two function to read txt file and to use it to extract image adresse and nom
and i use the functions here:
int i;
char fichier_radio[1024];
strcpy(fichier_radio,"liste_radio.txt");
int nombre_Radio = nombre_radio(fichier_radio);
recording_asset *assets = malloc(sizeof(recording_asset) * 5000);
printf("nombre %d",nombre_Radio);
char *adresse = malloc (sizeof (*adresse) * 256);
char *nom = malloc (sizeof (*nom) * 256);
char *image = malloc (sizeof (*image) * 256);
for(i=0; i<nombre_Radio; i++){
get_radio(i, fichier_radio, nom, adresse, image);
printf("image : ",image[i]);
}
Could you check fclose(fichier);:
If fichier is a null pointer, fclose should not be called. It results in a undefined behavior, hence might explain the crash you are observing.
You should put fclose(fichier); inside your if (fichier != NULL) check condition.
In nombre_radio, please initialize i to a proper value, you will return garbage value if fichier is NULL.

Resources