Segmentatio fault: 11 - Simple linked list c - c

I'm writing a code to get integers from the user and save them in a simple linked list until the numbers are -1 and -1. My problem is: When my list has more than 1 number, the program runs perfectly, but when it enter just one combination of numbers (1, for example) and then -1, I get a segmentation fault. Can anyone help me?

Read your warnings:
it is clear that if you exit in the first case your pointer isn't any good.

in addition to Grady answer, there's another fatal issue here in buscaEaddItem:
novo->RA=numRA;
novo->CodTopico=numCOD;
if(curr1==NULL) return novo;
else{
curr1->next=novo;
novo->next=NULL;
}
if curr1==NULL, then novo->next isn't set to NULL, so it's undefined behaviour. You have to set it in both cases, not only in the else part.

Related

Command line arguments in C- weird output

So I've written a code for a simple reverse Polish calculator that works only for positive numbers using command line arguments. It stores the numbers in a stack. The functions for push and pop are in a separate source file.
I've also written another program, to check the control flow of my previous program.
Here's the first program:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
void push(double);
double pop(void);
int main(int argc, char *argv[])
{
int c;
double op2;
while(--argc>0 && (c=(*++argv)[0]))
if(isdigit(c))
push(atof(argv[0]));
else if(c=='+')
push(pop()+pop());
else if(c=='-')
{
op2=pop();
push(pop()-op2);
}
else if(c=='*')
push(pop() * pop());
else
{
op2=pop();
push(pop()/op2);
}
printf("\n%f\n", pop());
return 0;
}
After I run this program, all the operators work, except '*'. For instance, if my input is ' ./pcalc 2 3 * ', then this is the output I get:
error: stack emptyerror: stack emptyerror: stack emptyerror: stack empty
-nan
If I interchange the conditions in the while loop, like this
while((c=(*++argv)[0]) && --argc>0)
then I get a 'segmentation fault (core dumped)' message for all operators.
To know the control flow of my program, I changed a part of the code to this:
while(--argc>0 && (c=(*++argv)[0]))
if(isdigit(c))
printf("\nentry1\n");
else if(c=='+')
printf("\nentry2\n");
else if(c=='-')
printf("\nentry3\n");
else if(c=='*')
printf("\nentry4\n");
else
printf("\nentry5\n");
The rest of the program was similar to the first one. On giving input as ' ./pcalc 2 3 * ', I get this output:
entry1
entry1
entry5
entry5
entry5
entry5
entry5
error: stack empty
0.000000
This means that control didn't go to the case for asterisk, and instead went to the else part.
When I interchange the conditions of the while loop, the output I get is similar as above( for all the operators, it shows the control flow, and for '*', it shows the same error as above), except, that it doesn't show the stack empty error for any operator, and shows instead a segmentation fault (core dumped) message.
So this is what I want to ask:
1) My first program worked for all operators, except '*'. What could be the reason? Why did the control go to the else part?
2) After interchanging the conditions, what memory was I accessing that I didn't have permission to? If it was NULL, then shouldn't that break the while loop anyway and proceed?
PS. This is my first question, so if there are any errors in my writing style, or if the question is too long, kindly let me know! We learn from our mistakes :)
Also, my compiler-GCC, OS-Ubuntu.
User xing is absolutely right.
To expand on it, the && operator is evaluated from left to right. If the left condition is not valid, then the right condition will not be evaluated as the return value is already known to be 0 (false).
Running ./pcalc 2 3 * will be expanded to ./pcalc 2 3 <all the files/directories in current working directory> so it will never push an operator on the operators' stack.
while(--argc>0 && (c=(*++argv)[0])) will first check if it is still within the arguments array before extracting the first element.
while((c=(*++argv)[0]) && --argc>0) will first try to extract a value, then check if it is still within the boundaries of the array. If not, well it has already segfaulted.

Problems with long input/output in C

I have to make a program in C that gets a non-defined amount of double values and prints them all increased by a certain percentage based on the number. The program should stop when the user enters a negative value. It all works well when I use a small quantity of numbers, but when the input consists of a larger amount of numbers the program prints just the last ones.
Here's my code:
#include <stdio.h>
int main()
{
double ins=0; //the input
while(ins>=0){
scanf("%lf",&ins);
if(ins<0){break;}
else{
if(ins<500){printf("%.2lf ",ins*1.15);}
else if(ins<=1000){printf("%.2lf ",ins*1.10);}
else {printf("%.2lf ",ins*1.05);}
}
}
return 0;
}
Additional information: Using GCC compiler.
Example of output the program should give for a specific input.
Input:
4003.31 1212.35 3414.31
4257.1 1394.37 1217.28
3602.85 4218.58 4994.8
1133.82 1086.48 2117.43
2253.86 3827.71 2170.16
1161.27 3069.77 1338.08
2791.99 3709.33 180.43
4555.77 318.58 1912.24
158.68 2106.49 4439.56
1247.34 -0.79
Output I should get:
4203.48 1272.97 3585.03 4469.96
1464.09 1278.14 3782.99 4429.51
5244.54 1190.51 1140.80 2223.30
2366.55 4019.10 2278.67 1219.33
3223.26 1404.98 2931.59 3894.80
207.49 4783.56 366.37 2007.85 182.48
2211.81 4661.54 1309.71
What could I do to make the program work correctly not just with small amounts but also with quantities like the above ?
Edit: the output I'm getting with the above input is "1309.71",which is just the last number of the full output I should receive.
Note: You have a simple logic error. Because you are checking ins<500 before ins<=100 you can never hit the ins<=100 case.
Your code and sample data works for me. Can you give a more detailed description of the problem?
Well, I found out the solution. As you guys said that the code was working properly for you I tested it using another command line interface. And now the output is correct, so it seems like the one I was using before (Windows CMD) was deleting outputted information when that information reached a certain limit, maybe a small buffer size or something like that. Thank you for the help guys !!

C: Segmentation fault and maybe GDB is lying to me

Here is a C function that segfaults:
void compileShaders(OGL_STATE_T *state) {
// First testing to see if I can access object properly. Correctly outputs:
// nsHandle: 6
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
// Next testing if glCreateProgram() returns proper value. Correctly outputs:
// glCreateProgram: 1
printf("glCreateProgram: %d\n", glCreateProgram());
// Then the program segfaults on the following line according to gdb
state->nsHandle = glCreateProgram();
}
For the record state->nsHandle is of type GLuint and glCreateProgram() returns a GLuint so that shouldn't be my problem.
gdb says that my program segfaults on line 303 which is actually the comment line before that line. I don't know if that actually matters.
Is gdb lying to me? How do I debug this?
EDIT:
Turned off optimizations (-O3) and now it's working. If somebody could explain why that would be great though.
EDIT 2:
For the purpose of the comments, here's a watered down version of the important components:
typedef struct {
GLuint nsHandle;
} OGL_STATE_T;
int main (int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
compileShaders(state);
}
EDIT 3:
Here's a test I did:
int main(int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
// Assign value and try to print it in other function
state->nsHandle = 5;
compileShaders(state);
}
void compileShaders(OGL_STATE_T *state) {
// Test to see if the first call to state is getting optimized out
// Correctly outputs:
// nsHandle (At entry): 5
printf("nsHandle (At entry): %d\n", state->nsHandle);
}
Not sure if that helps anything or if the compiler would actually optimize the value from the main function.
EDIT 4:
Printed out pointer address in main and compileShaders and everything matches. So I'm gonna assume it's segfaulting somewhere else and gdb is lying to me about which line is actually causing it.
This is going to be guesswork based on what you have, but with optimization on this line:
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
is probably optimized to just
printf("nsHandle: 6\n");
So the first access to state is where the segfault is. With optimization on GDB can report odd line numbers for where the issue is because the running code may no longer map cleanly to source code lines as you can see from the example above.
As mentioned in the comments, state is almost certainly not initialized. Some other difference in the optimized code is causing it to point to an invalid memory area whereas the non-optimized code it's pointing somewhere valid.
This might happen if you're doing something with pointers directly that prevents the optimizer from 'seeing' that a given variable is used.
A sanity check would be useful to check that state != 0 but it'll not help if it's non-zero but invalid.
You'd need to post the calling code for anyone to tell you more. However, you asked how to debug it -- I would print (or use GDB to view) the value of state when that function is entered, I imagine it will be vastly different in optimized and non-optimized versions. Then track back to the function call to work out why that's the case.
EDIT
You posted the calling code -- that should be fine. Are you getting warnings when compiling (turn all the warnings on with -Wall). In any case my advice about printing the value of state in different scenarios still stands.
(removed comment about adding & since you edited the question again)
When you optimize your program, there is no more 1:1 mapping between source lines and emmitted code.
Typically, the compiler will reorder the code to be more efficient for your CPU, or will inline function call, etc...
This code is wrong:
*state=_state
It should be:
*state=&_state
Well, you edited your post, so ignore the above fix.
Check for the NULL condition before de-referencing the pointer or reading it. If the values you pass are NULL or if the values stored are NULL then you will hit segfault without performing any checks.
FYI: GDB Can't Lie !
I ended up starting a new thread with more relevant information and somebody found the answer. New thread is here:
GCC: Segmentation fault and debugging program that only crashes when optimized

Getting a segfault where gdb doesn't recognize

I am trying to print out the contents of a 2 dimensional array starting from a certain location in the array (since not all elements of the array are filled). The array contains pointers to a data structure I created called a node. Here is the print code:
void repository_print(int print_elements){
node *travTemp;
travTemp = main_list[highest_level][0];
while((travTemp->down)!=NULL){
while((travTemp->next)!=NULL){
printf(" {%d, %d}", travTemp->key, travTemp->d);
travTemp = travTemp->next;
}
travTemp = travTemp->down;
printf("\n");
}
}
Basically the array holds pointers to node elements in a sorted fashion. Each node contains a "key" attribute and a "d" attribute and I am just trying to go level by level and print out the {key, d} records cleanly. I keep getting a segfault when I call the print command in my main. I tried using gdb to debug it but it won't give me an actual line. It just says:
#0 0x0000000000400b2e in repository_print ()
#1 0x0000000000400722 in main ()
Does anyone how I can find the seg fault or why the seg fault is occurring? Thanks.
EDIT:
I did try compiling with -g and found that the error is occurring at the line "while((travTemp->next)!=NULL)". This is confusing to me because this attribute should not be NULL. I'll have to check the rest of my code. The main_list declaration is as follows in case anyone needs to know:
node *main_list[MAX_HEIGHT][MAX_LEVEL];
EDIT:
So following Felipe's advice I changed my print function to the following:
node *travTemp;
travTemp = main_list[highest_level][0];
while(travTemp!=NULL && (travTemp->down)!=NULL){
printf(" {%d, %d}", travTemp->next->key, travTemp->next->d);
travTemp = travTemp->next;
}
travTemp = main_list[highest_level+1][0];
printf("\n");
However, now, I'm getting a seg fault at the print statement line. If travTemp->next does not equal NULL what's the problem with travTemp->next->key? I have no idea why since these values should exist in the repository.
If main_list[highest_level][0] is NULL, then your initial attempt to test travTemp->next will fail. #Filipe has addressed getting more debugging info in the comments.
Update: if it isn't NULL but following travTemp seems to be the problem, perhaps it is some other illegal value. Not seeing how main_list was filled, can't say more than that.

C programming. Why does 'this' code work but not 'that' code?

Hello I am studying for a test for an intro to C programming class and yesterday I was trying to write this program to print out the even prime numbers between 2 and whatever number the user enters and I spent about 2 hours trying to write it properly and eventually I did it. I have 2 pictures I uploaded below. One of which displays the correct code and the correct output. The other shows one of my first attempts at the problem which didn't work correctly, I went back and made it as similar to the working code as I could without directly copying and pasting everything.
unfortunately new users aren't allowed to post pictures hopefully these links below will work.
This fails, it doesn't print all numbers in range with natural square root:
for (i = 2; i <= x; i++)
{
//non relevant line
a = sqrt(i);
aa = a * a;
if (aa == i);
printf("%d ",i);
}
source: http://i.imgur.com/WGG6n.jpg
While this succeeds, and prints even numbers with natural sqaure root
for (i = 2; i <= x; i++)
{
a = sqrt(i);
aa = a * a;
if (aa == i && ((i/2) *2) == i)
printf("%d ", i);
}
source: http://i.imgur.com/Kpvpq.jpg
Hopefully you can see and read the screen shots I have here. I know that the 'incorrect code' picture does not have the (i/2)*2 == i part but I figured that it would still print just the odd and even numbers, it also has the code to calculate "sqrd" but that shouldn't affect the output. Please correct me if I'm wrong on that last part though.
And Yes I am using Dev-C++ which I've read is kinda crappy of a program but I initally did this on code::blocks and it did the same thing...
Please I would very much appreciate any advice or suggestions as to what I did wrong 2 hours prior to actually getting the darn code to work for me.
Thank you,
Adam
your code in 'that' includes:
if (aa == i);
// ^
printf(...);
[note the ; at the end of the if condition]
Thus, if aa == i - an empty statement happens, and the print always occures, because it is out of the scope of the if statement.
To avoid this issue in the future, you might want to use explicit scoping1 [using {, } after control flow statements] - at least during your first steps of programming the language.
1: spartan programmers will probably hate this statement
Such errors are common. I use "step Over", "Step Into", "Break Points" and "watch window" to debug my program. Using these options, you can execute your program line by line and keep track of the variables used in each line. This way, u'll know which line is not getting executed in the desired way.

Resources