c variable turning into -17918 when incremented - c

hi i am making a programming language that will run on the nintendo gameboy in c
which is why you will see some functions like waitpad();
but this question is unrelated the the gameboy librarys
for some reason when ever i try to increment a certain variable in my main.c file:
#include <stdio.h>
#include <gb/gb.h>
#include "convert.h"
#include "display.h"
#include "input.h"
#include "functions.h"
#include "interpreter.h"
unsigned char cnt[5] = {1,2,3,4,5};//cnt is short for counters
unsigned char k = 0;
unsigned char running = 1;
unsigned char memory[2048];
unsigned char code[2048];
int main()
{
Clear_mem();
Clear_code();
while(running == 1) {
display(cnt[0],cnt[1],cnt[2],cnt[3],cnt[4]);
printf("cnt[0] = %d\n", cnt[0]);
cnt[0]++;//turns into -17918
printf("Press Start To Enter Next Character\n");
waitpad(J_START);
code[k] = input();
interpret(code[k]);
k++;
}
return 0;
}
cnt[0] turns into -17918
can anyone see any problem that would cause it to behave this way?

You ask if anyone sees a problem, well - yes, here is a problem:
unsigned char k = 0;
unsigned char running = 1;
unsigned char code[2048];
while(running == 1) {
code[k] = input();
k++;
}
If k >= 2048, then code[k] = ... will cause a memory-override.
After a memory-override, pretty much anything can happens (undefined behavior).
Having said that, the value of k can be larger than 2047 only if CHAR_BIT is larger than 11.
Add #include <limits.h> to your program and make sure that CHAR_BIT is not larger than 11.

You have to convert it to an integer, because that's what you're trying to print:
printf("cnt[0] = %d\n", (int) cnt[0]);
When you're using a variadic function like printf, you have to make sure you're passing the right type. Check your compiler warning settings, new compilers can easily detect these kind of problems.

if you want to print the character value of your character variable you should print it like this:
printf("cnt[0] = %c\n", cnt[0]);
If you print it using %d the expansion of the character to a size of int could be negative for characters over half a character's size (0x80 and up).
If you insist on printing it as an int cast the variable like this:
printf("cnt[0] = %d\n", (int)cnt[0]);

Related

how to resolve the segmentation fault error in the given c program

this is a program to find the maximum occurrence of the largest number in an array.
how to resolve the segmentation fault error in this? hackerrank problem
/* given:
1<n<10^5
1<arrayNum[n] <10^7 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main(){
signed long int max,n,d,a,arrayNum[n];
signed long int max_count; scanf("%ld",&n);
for( a=0; a < n; a++)
{
scanf("%ld",&arrayNum[a]);
}
max = arrayNum[0];
max_count = 1;
for (int a = 0; a < n; ++a)
{
if (arrayNum[a] == max)
max_count++;
else if (arrayNum[a] > max)
{
max_count = 1;
max = arrayNum[a];
}
}d=max_count;
printf("%ld",d);
return 0;}
int main(){
signed long int max,n,d,a,arrayNum[n]; //<< the problem is here,
// the content of n is indeterminate
// at that state
signed long int max_count; scanf("%ld",&n);
...
arrayNum[n] is declared before the value of n is entered by the user.
Just change your code to something like that:
int main(){
signed long int max,n,d,a;
signed long int max_count;
scanf("%ld",&n);
signed long arrayNum[n];
...
There may be other issues though.
And as already stated by others: fix the code indentation. Correctly indentend/formatted code is essential so your code can be understood by others (and even more important by yourself).
To resolve a segmentation fault, the best way is to:
Understand what you do (do you really get what each line of your program does ?).
Fix the errors and warnings given by the compiler.
Compile with debug symbols (-g or -g3) and use a debugger (gdb for example) to find where is your segmentation fault.
First you should check your code indentation, make it more clear for us to read.
Then, give us more information about your segfault : where does it occurs ? You can use tools like Valgrind (on Linux) to find this kind of informations. You just have to build your program with debugging flags (-g on GCC) and run the program with GCC.
The problem here is arrayNum[n] which have the size of a non-initialized variable (n). So this array does not have any allocated space. The access to arrayNum through scanf() create this segfault.

Two almost exactly the same programs but different output

Hi I have made a very simple program that should work but it don't:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int main(int argc, char *argv[]) {
int usedNumbers[256];
memset(usedNumbers,0,256);
srand(time(NULL));
for(int i=0; i<256; ++i){
while(1){
int r = rand()%256;
if( !usedNumbers[r] ){
usedNumbers[r] = 1;
break;
}
printf("Test: %03d -> %03d\n", i, r);
}
}
return 0;
}
The idea of the program is to print numbers from 0 to 255 on the screen in the random order but the program stops on 84th number on 32 computers and 144th number on 64 bit computers. If i only move the "int usedNumbers[256];" above the function like that:
#include <string.h>
int usedNumbers[256];
int main(int argc, char *argv[]) {
Program works as it supposed to.
Why is it that?
I am using the newest GNU/GCC compiler and C11 standard.
The usedNumbers inside main is a local variable and these are not zero-initialized (i.e. they can contain garbage). Since you only use memset(..., 256), only the first 256 bytes are zero-initialized, and the rest (e.g. half or three quarters of the array -- or more, depending on the size of int) is not.
The usedNumbers outside main is a global variable, however, and these are completely zero-initialized, even without memset. So there, you really have an empty array with no garbage in it, and that is why that works as expected.
So do:
memset(usedNumbers, 0, sizeof(usedNumbers));
and both versions should produce the same, expected result.

Conversion of integer to char array in C

I'm developing an ARM embedded application. I'm kind of stuck on a silly problem - I have an array of unsigned 8-bit integers:
uint8_t days[42] = { 0 };
It's initialized with some data - the initialization algorithm introduces a lot of variables confusing and irrelevant to the problem, so I will not repost it here. I see this array in the debugger variable watch, and I'm certain it is filled with integer values from 0 to 31.
I'd like to take any element of this array, say 15th, and convert it to char* so that it can be displayed on my LCD screen. I rewrite it using sprintf function:
char d[3] = { '0', '0', '0' };
sprintf(d, "%d", days[15]);
Just one note: no, I can't use the stdlib itoa() function, because it does not conform to MISRA-C standards, which I am obliged to follow.
As a result, I only get a binary zero value in my d buffer. Any ideas?
For MISRA-C compliance, you can certainly not use sprintf() or anything else from stdio.h either. You generally want to avoid sprintf like the plague on any embedded system anyhow.
Writing a simple decimal integer to string conversion routine is quite basic stuff... here's my attempt of a MISRA-C (2004 and 2012) compatible version:
#include <stdint.h>
void dec_to_str (char* str, uint32_t val, size_t digits);
int main (void)
{
char str[3u + 1u]; // assuming you want null terminated strings?
dec_to_str(str, 31u, 3u);
return 0;
}
void dec_to_str (char* str, uint32_t val, size_t digits)
{
size_t i=1u;
for(; i<=digits; i++)
{
str[digits-i] = (char)((val % 10u) + '0');
val/=10u;
}
str[i-1u] = '\0'; // assuming you want null terminated strings?
}
Note: the uint32_t variable could get swapped out for an uint8_t, but then you need to add type casts all over the place, to prevent implicit type promotions, as required by MISRA. The code will then turn really ugly, like this:
str[digits-i] = (char)(uint8_t)((uint8_t)(val % 10u) + '0');
The only sane thing to do then, is to split that mess into several lines:
uint8_t ch = (uint8_t)(val % 10u);
ch = (uint8_t)(ch + '0');
str[digits-i] = (char)ch;
#include "stdafx.h"
#include <stdio.h>
int days[2] = {12,14};
char d[3] = {'0', '0', 0};
int _tmain(int argc, _TCHAR* argv[])
{
d[0] = days[1] / 10 + 0x30; // convert 10's digit to ascii
d[1] = days[1] % 10 + 0x30; // convert 1's digit to ascii
// Debugging help
printf(d);
getchar();
return 0;
}

strcspn() stopping at a period

I'm writing a function that should parse a string containing a description of a dice roll, for instance "2*1d8+2". I extract the four values OK when they are integers, but I want to be able to use floats as well for the multiplier and the addition at the end. Things get nasty when I try to parse such a string: "1.8*1d8+2.5".
I have determined that the problem is with the function strcspn. I ask it to parse the input string s (which contains the dice string) and stop at either an asterisk or an 'x':
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
The function should return 3, as the asterisk is at the 4th position. However, it seems to stop on the decimal separator (period) and returns 1.
It's not that I can't continue writing my function without this, as there are other ways to get things done, but still I'm curious why such a thing would happen. Has anyone ever encountered this problem before?
[EDIT]
Nevermind, I've found the answer, and it was my stupidity rather than the compiler playing tricks on me. I used this code:
if (l = strcspn(s,"*x") < strlen(s)) {
...
which returned 1 (or true) because strcspn(s,"*x") < strlen(s) evaluates to true - and was assigned to the l variable. I should have added parentheses:
if ((l = strcspn(s,"*x")) < strlen(s)) {
...
Thanks for your answers nonetheless, particularly #sleske, who made me analyse my code more deeply (which led to finding the answer).
There must be an error somewhere else. I wrote a test program:
#include <stdio.h>
#include <string.h>
void main(){
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("l: %d\n", l);
}
and compiled it with gcc on Linux. On my system, it outputs "3".
Please post a complete, working example that exhibits the problem. Then we'll see...
Your code works just as you posted it for me1.
#include <stdio.h>
#include <string.h>
int main(void) {
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("%zd (%.*s)\n", l, (int)l, s);
return 0;
}
so ross$ ./a.out
3 (1.8)
1. Mac OS X 10.6.4
I'd use sscanf instead of manually finding stop points and parsing myself. You can get your integers and floats easily out of the string with that.
This code:
#include <stdio.h>
#include <string.h>
int main(void)
{
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("<<%s>> %zd <<%s>>\n", s, l, s+l);
return 0;
}
produces this answer on MacOS 10.6.4 (GCC 4.5.1):
<<1.8*1d8+2.5>> 3 <<*1d8+2.5>>
If your compiler and library does not produce the same answer, get a fixed/upgraded version of the software.
(NB: The 'z' modifier in the printf() format string is a C99 feature - it indicates that the type of the parameter is size_t.)

Printing a random number returns a negative number. (/dev/urandom)

I have written a source code to print random numbers within a specified limit.But it is also returning some negative numbers,is this normal?If not how do I rectify it?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main( int argc, char* argv[])
{
int fd, n;
fd = open("/dev/urandom", O_RDONLY);
if(fd == -1)
printf("ERROR: Cannot Open %s\n",argv[1]);
read(fd, &n, sizeof(n)); //n=random number
printf("%d\n",1+n%6); //limiting n
/* 1+n%6 should give me random numbers only between
1-6(correct me if I'm wrong),
but somehow it even gives negative numbers*/
close(fd);
}
In case the random number you read is negative (which is certainly possible), the modulus of it can also be negative. You should use an unsigned integer in order to make sure the result is in the range you want.
More information can be found here.
1 + n % 6 does not magically constrain the result to between 0-6. Run this to see.
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("%d\n", 1 + (-23) % 6);
return 0;
}
Wow, even I thought that the modulo operator when applied like
c=a%b
restricts c between integers [0,b-1].
However as K&R writes (pg 39, 2nd ed):
The expression x % yproduces the
remainder when x is divided by y, and
thus is zero when y divides x exactly.
So in effect what happens is:
c = sign(a) * ( abs(a)%abs(b) )
(where sign(a)=-1 for a<0 and +1 for a>=0)
It would be great if somebody could point out an actual reference to this behaviour in a book or C standard. This is what I figured out after experimentation with GCC v4.4.1.
Thanks for the great question. You kind of cleared my understanding of C modulus operator.

Resources