I have a segmentation fault in the following code, but do not understand why. This is part of a larger program, where fsi is a double and is calculated immediately preceeding this block of code. The program calculates fsi over a number of years (lt) and I want to print the output as an array (fsi.dat). It prints the first value but then seg faults. What am I missing?
Here is the code:
FILE *fpout;
int lt;
double silicate[lt];
fpout = fopen("fsi.dat","w");
if(fpout == NULL)
ferrx("writedat(): Can't open file to write: fsi.dat");
for(i=1;i<=lt;i++)
silicate[i] = fsi;
fprintf(fpout,"%18.15f \n", silicate[i]);
fclose(fpout);
You need to put brackets in order to execute more than one statement in a for
for(i=1;i<=lt;i++) {
silicate[i] = fsi;
fprintf(fpout,"%18.15f \n", silicate[i]);
}
The version you have is equivalent to
for(i=1;i<=lt;i++) {
silicate[i] = fsi;
}
fprintf(fpout,"%18.15f \n", silicate[i]);
the last line executing with i = lt + 1
for(i=1;i<=lt;i++)
silicate[i] = fsi;
is wrong, indexes in C are zero-based. So your valid indexes are 0 .. (lt-1)
Related
I'm working in C, Linux terminal. I need to find a pattern in a text and recolor it. GDB debugging can locate the function that is causing the problem via (gdb) backtrace, but it shows me a terrible message when I try to find the exact line:
Error
Program received signal SIGSEGV, Segmentation fault.
strstr_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S:40
40 ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S: No such file or dir
ectory.
(gbd)
The broken function is find_and_recolor:
char* my_replace(char *text, char* replacement)
{
int lgreplacement = strlen(replacement);
int lgtext = strlen(text);
char *aux = (char*)malloc((lgreplacement + lgtext + 10) * sizeof(char));
strcpy(aux, replacement);
strcat(aux, text);
return(aux);
}
char* find_and_recolor(char* text, char* pattern)
{
int lgpattern = strlen(pattern);
int lgreplace = lgpattern + 10;//there are exactly 10 characters that must be inserted along the pattern word
int dif = 0;
char *p;
char *replacement = (char*)malloc(lgreplace * sizeof(char));
strcpy(replacement, "\e[0;31m");
strcat(replacement, pattern);
strcat(replacement, "\e[m");//to recolor a word in red, that word must be surrounded by those characters
while(p = strstr(text + dif, pattern))
{
p = my_replace(p, replacement);
p += lgreplace;
dif = p - text;
}
free(replacement);
return strdup(text);
}
it shows me a terrible message when I try to find the exact line:
There is nothing terrible, weird or unusual about this message, you just need to learn proper debugging technique.
What's happening is that the segmentation fault doesn't happen in your code, it happens inside GLIBC code (inside strstr), because you called strstr with bad arguments.
To find which call to strstr that was, use GDB up command to step out of GLIBC code, and into your code. Once you are inside find_and_recolor, you would be able to see the exact line, and print values of text, dif and pattern which caused your crash (assuming you compiled your code for debugging, i.e. with the -g flag).
Updating diff to p-text in while loop where both pointer points to different array doesn't make sense. It is undefined behavior.
Also code has other issues.
Uninitialized variable.
Less optimized as number of call can be reduced.
I'm trying to get my code to convert a text file with 3 columns, xcoor, ycoor, and a symbol with 2 characters into a 30x30 map that prints the 2nd character of the symbol with the rest of the spaces being filled with a '.' However, my code doesn't seem to run, and I get a segmentation error when I try inputting the text file, what am I doing wrong? Thanks in advance
int main(void)
{
char grid[30][30];
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
grid[i][j]='.';
}
}
int xcoor,ycoor;
char symbol[2];
while((xcoor!=0)||(scanf("%d",&xcoor)))
{
while(xcoor==0){
scanf("%d",&xcoor);
}
scanf("%d %c%c",&ycoor,&symbol[0],&symbol[1]);
grid[xcoor-1][ycoor-1]=symbol[1];
}
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
printf("%c ",grid[i][j]);
}
printf("\n");
}
return 0;
}
This may not cover ALL of your errors, but immediately I see this:
int xcoor,ycoor;
char symbol[2];
while((xcoor!=0)
Do you think xcoor has a valid value right now? Should it? Because it doesn't. You've created a variable, then before actually setting it to anything, you are checking its value.
It's more than likely your scanf call that's giving you trouble. Regardless, try actually setting these variables. It will most likely fix your issues.
See here for more info: Is reading from unallocated memory safe?
You are using an uninitialized variable xcoor in the conditional of the while statement.
You can fix that by initializing xcoor.
More importantly, you can simplify the code for reading user data and the related error checks. Here's what I suggest:
while ( scanf("%d%d %c%c", &xcoor, &ycoor, &symbol[0], &symbol[1]) == 4 )
{
if ( xcoor < 0 || xcoor >= 30 )
{
// Deal with problem.
fprintf(stderr, "Out or range value of xcoor: %d\n", xcoor);
exit(1);
}
if ( ycoor < 0 || ycoor >= 30 )
{
// Deal with problem.
fprintf(stderr, "Out or range value of ycoor: %d\n", ycoor);
exit(1);
}
grid[xcoor-1][ycoor-1] = symbol[1];
}
I have written a function that is supposed to read the number of sentences in a .txt file, but when the function is called and done, it gives me a value of 0.
This program over all has 3 more functions to figure out different properties of the file and I have them working great. This one is laid out the same way I wrote my other functions just looking for some advice on why I am getting 0 as my number of sentences.
void ptrCntS (FILE* sp1, int sCount)
{
char sentence = 'O';
int myChr;
if (!(sp1 = fopen("Hello.txt", "r")))
{
printf("error opening Hello.txt");
return(1);
}
while ((myChr = fgetc(sp1)) != EOF)
{
if ('.')
{
sentence ='O';
}
else if (sentence == 'O')
{
sCount++;
sentence = 'I';
}
}
fclose(sp1);
printf ("Total number of sentences are:\t%d", sCount);
return;
}
instead of return use return(sCount);
and assign the return value to some int variable in calling function
like
int sentCount;
.
.
.
sentCount=ptrCntS (param1,param2);
if ('.') is always true, thus else... code never reached. Use if( myChr == '.' ) instead.
Function compiles now and runs properly. This function is being called from a switch in a previous function where I had my addresses set and included my print statement for the totals so that I would not have to write another function in the end to call on all my counts and print their results. Instead I set my case 'A': to call all of my counting functions(in this case that is what the original code is) and than display my results. I am sorry for any lengthiness or my hard to understand writing I am new to the C language and I am having a hard time grasping the literature but making some process on understanding the syntax.
Whenever i try to read the char from file and try to access it i am getting error . My code is :
while((c=fgetc(f))!=EOF) {
if(c == '\n') {
str[i]='\0';
Info* inf = new Info();
inf->getInputFromFile(str);
if((table->insert(inf))==0)
cout<<"exist."<<endl;
//delete inf;
for(int j =0; j<50;j++)
str[j]='\0';
i=0;
} else {
str[i] = c;
i++;
}
But here when ever I try to give a dummy word such as : inf->getInputFromFile("Hello");
I am not getting any error. I can't also find the error using debuggin because when I press F8(CodeBlocks IDE) my debugger start and it doesn't stop any line. i.e. i don't find any error when running the program using F8.
Here is the input file content :
int, INTEGER
myFunction, FUNCTION
x, IDENTIFIER
5, NUMBER
x, Identity
char, CHARACTER
fl, FLOAT
dbl, DOUBLE
you, MEINTHIS
dlt, DELETE
hel, HELLOWORLD
string, STRING
How to read a file in C was answered here: In C, how should I read a text file and print all strings And I think that's the answer you are searching for.
So I am trying to link a list together from user input their own file , but when I try printing it only prints the the first line, I believe the problem lies somewhere below in my code fragment, I think currp is not getting currp-next.
while ((fscanf( fpin, "'%[^']' %f %f %d" ,currp->name, &currp->cost,
&currp->weight, &currp->dam) ==4 ))
{
prev = currp;
currp->next = malloc(sizeof(item_t));
assert(currp->next);
currp = currp->next;
}
prev->next = NULL;
free(currp);
fclose(fpin);
return (itb);
I guess currp does get next , but you just don't assign it .
Just check it ,
Add a printf of currp->next as an integer
It will represent it's address if address changes
Then the problem is in assertion .