Board game functions - c

I have made a program to a board game. My problem is a function, so that certain fields transport the player back or forward. Apparently the thing I did doesn't work.
int numbers()
{
int maxscore;
int numbers[10];
maxscore = enter();
srand(time(NULL));
int nonumbers[3] = {0, 1, maxscore}; //to initialize the scores there shouldn't be a badfield
numbers[10] = rand() % maxscore + 1;
if(numbers[10] == nonumbers[3])
{
numbers[10] = rand() % maxscore + 1;
}
return numbers;
}
int badfields = numbers();
if(score[i] == badfields)
{
printf("Player %d. goes 5 fields backwards", playershown);
score[i] = score[i] - 5;
printf("This player is now in %d Field", score[i]);
}
Somehow I have to repeat the process of entering the maximum score.

I won't directly answer the "question" because there is no "question" to be answered. As others have pointed out in the comments, you need to be more specific and provide a proper description of your problem. But I can still provide the following feedback:
It seems to me you don't quite understand arrays and their indexing. For example, this line should give you a segmentation fault error, or at the very least make a comparison with an unknown value:
if(numbers[10] == nonumbers[3])
This is because your nonumbers array has 3 elements, and thus they should be addressed as nonumbers[0], nonumbers[1] or nonumbers[2] (or, in general, as Weather Vane put it in the comments, from nonumbers[0] to nonumbers[array_lenght-1]). nonumbers[3] will access an undefined position in memory. Your problem could be related to this.
Note that neither me nor anybody is going to review your entire code
to find the error. As stated above, please be more specific.
Also, are you sure you got rid of all compiler errors? Because further down your code you have an uninitialized variable i. To be sure you got rid of all potentially nasty errors, open the terminal (I'm assuming you are on linux) and use the following command to compile your program:
gcc *.c -Wall -Wextra -o program
Then run it with:
./program

Related

Valgrind Errors - Conditional Jump or move depends on uninitialised values

img of error
Above is an error I have been getting, in relation to this line in my program:
storedData[k] = min(dist[index1][k],dist[index2][k]);
Now here is the surrounding functions to this line:
for(int k = 0; k <arraySize; k++){
if(k!= index1 && k != index2){
if(method == SINGLE_LINKAGE){
storedData[k] = min(dist[index1][k],dist[index2][k]);
} else {
storedData[k] = max(dist[index1][k],dist[index2][k]);
}
}
}
Now after playing around with it for quite a while, I realised that the issue it has is with the incrementing 'k' variable in the for loop. More specifically it is worried that when used as an index in dist, the value returned will be uninitialised. Now in terms of functionality, my program works fine and does everything I want it to do. More notably, I have also initialised this function elsewhere in a helper function which is why this confuses me more. I have initialised all the values from index 0-arraysize which in my head means this should never be an issue. Im not sure if maybe this is caused because its done outside of the main function or something. Regardless it keeps giving me grief and I would like to fix it.
You need to work back from the error to its origin. Even if you are initializing your arrays, it is possible that something is 'uninitializing' them again afterwards. memcheck does not flag uninitialized data when it is copied, only when it affects the outcome.
So in pseudo-code you might have
Array arr;
Scalar uninit; // never initialized
init_array(arr);
// do some stuff
arr[3] = uninit; // no error here
for (i = 1 to arr.size)
store[i] = max(arr[i], arr[i-1]; // errors for i == 3 and 4
There are two things that you could try. Firstly, try some 'printf' debugging, something like
for(int k = 0; k <arraySize; k++) {
if(k!= index1 && k != index2) {
fprintf(stderr, "DEBUG: k %d index1 %d index2 %d\n", k, index1, index2);
// as before
Then run Valgrind without a log file. You should then be able to see which indices cause the error(s).
Next, try using ggbserver. Run valgrind in one terminal with
valgrind --vgdb-error=0 prog args
and then run gdb in a second terminal to attach (see the text that is output in the 1st terminal for the commands to use).
You can then use gdb as usual (except no 'run') to control your guest app, with the additional ability to run valgrind monitor commands.

Command line arguments using if/else statements in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am new to programming and this one has me baffled.
I am writing a function to be called by main that takes the command line arguments and stores them in a struct to use later. This specific example is for use with image editing, but can be used anywhere.
Desired performance: Function takes arguments from the command line. Three specific arguments are identified and checked for: -h, -o and -t. If present they will alter the struct values. Arguments -o and -t store the arguments immediately following them into their respective struct fields. Any argument that is not -h or does not have -o or -t preceding it is assumed to be the input file name and stored in flag->inputFile. If all arguments are accounted for, then flag->inputFile should remain NULL and can be tested for in the main function and program terminated if this is true.
Problem: When there is no input file specified (using the above parameters) flag->inputFile keeps getting set to -o when it is included as an argument.
Solution: Thanks to Scott this question has been answered by replacing several if statements with else if has now seemed to fix the problem, and the function appears to be working as desired.
My understanding of what was happening is that the else statement was being run in every iteration of i unless the -t argument was included, since it was the statement immediately before the else
The compiler I'm using is gcc and this is my code. (I know my struct is not packed, I'm still trying to get my head around this and can't see how it would result in what I'm seeing. Segmentation fault, yes, but not this?)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct PROMPTFLAGS {
int help; // Change from NULL if -h argument present
char * outputFile; // Store argument after -o as the output file
char * inputFile; // Argument not paired with a flag stored here as input file
float threshold; // Stores a value to use in image manipulation in main
};
struct PROMPTFLAGS * parsargs(int argc, char * argv[]) {
struct PROMPTFLAGS* flag = malloc(sizeof(struct PROMPTFLAGS));
int i;
printf("argc: %d\n",argc);
for (i = 1; i < argc; i++) {
char * arg = argv[i];
int str_aft = i+1; // Allows the next string to be used in this iteration of the loop
if (strcmp(arg,"-h") == 0) {
flag->help = 1;
}
if (strcmp(arg,"-o") == 0) { // Changing this to 'else if' seems to be a fix
flag->outputFile = argv[str_aft];
i++; // Skips over next arg since already read by argv[str_aft]
}
if (strcmp(arg,"-t") == 0) { // Changing this to 'else if' seems to be a fix
flag->threshold = strtod(argv[str_aft],NULL);
i++; // Skips over next arg since already read by argv[str_aft]
}
else {
flag->inputFile = arg;
}
}
return flag;
}
int main(int argc, char* argv[]) {
struct PROMPTFLAGS * flags;
flags = parsargs(argc, argv);
printf("Help = %d\n",flags.help);
printf("Output = %s\n",flags.outputFile);
printf("Input = %s\n",flags.inputFile);
printf("Threshold = %s\n",flags.threshold);
return 0;
}
I apologise for the poor format of the first version of this question and hope that this edit is better. I have made the functions' desired outcomes and the problem I encountered clearer and removed most of the test prints I had through the code and added some comments. I have also included the solution to my problem (provided by another user) and my understanding of what was happening in the broken code.
If people still think this is a poor question or of no use to anyone else then I'm happy to take it down, but have edited and left it up hoping it can help someone else.
This is my first post on stack overflow and I thank everyone for their help and patience while I learn to code and the best manner to post questions.
You set flag->inputFile = arg whenever arg is not "-t" (the else after testing for "-t"). I'm not sure when you want to assign to this field, but I am sure this isn't the right logic for it. For example, if you wanted to do this when arg is none of the other specific flags you are looking for, you should be using if ... else if ... else if ... else.

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

Function crashing in release mode but runs flawless in debugger

My program crashes on this function on the 7th line, when I call malloc() when I run in release mode I get the `Program.exe has stopped working message, and when I run in debugger, most of the time it succeeds but sometimes I get this message (especially on larger input):
MONOM* polynomialsProduct(MONOM* poly1, int size1, MONOM* poly2, int size2, int* productSize)
{
int i1, i2;
int phSize = 1, logSize = 0;
MONOM* product;
product = (MONOM*)malloc(phSize*sizeof(MONOM));
monomAllocationVerification(product);
for (i1 = 0; i1 < size1; i1++)
{
for (i2 = 0; i2 < size2; i2++)
{
if (logSize == phSize)
{
phSize *= 2;
product = (MONOM*)realloc(product,phSize*sizeof(MONOM));
monomAllocationVerification(product);
}
product[logSize].coefficient = poly1[i1].coefficient * poly2[i2].coefficient;
product[logSize].power = poly1[i1].power + poly2[i2].power;
logSize++;
}
}
mergeSort(product,logSize);
*productSize = sumMonomsWithSamePower(product, logSize);
return product;
}
I understand that I'm dealing with memory errors and problems, but is there any quick way to analyze my code and look for memory errors? I look at my code a dozen of times looking for this kind of errors and found nothing. (I didn't want to post the code here since its 420 lines long).
First of all, if heap corruption is detected on the first malloc, that means it happened earlier (not in this function or on previous pass). So the problem may lie outside this code.
However, the code also looks suspicious to me.
monomAllocationVerification has no size parameter, so it should work on one monom only, yet you call it only once after realloc on pointer to first element, despite having allocated space for quite a few monoms. Please clarify your decision.
It is a bit unclear why sumMonomsWithSamePower should return a size, and thus modify an array to store a value. May be a quirk, but still suspicious.
UPDATE
The problem was in other functions; a few reallocs with wrong size.
I would check the return value of malloc() and use perror() to describe what error has occured. Also here is the documentation for malloc() and perror().
if((product = (MONOM*)malloc(phSize*sizeof(MONOM))) == NULL)
{
perror("ERROR: Failed to malloc ");
return 1;
//perror() will display a system specified string to describe the error it may tell you the error
}
Also do you know the size of MONOM? If not add the following line to your code.
printf("MONOM SIZE = %i\n", sizeof(MONOM));

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