Two almost exactly the same programs but different output - c

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.

Related

Generate random string in c

In this code I'm generate random number in specific range, but I want the out put of array must be
m1,m1,m3,m1 ..
I mean adding the word "host" to every number that is generate randomly, how can do this please?
this is code
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
int a[50];
srand(time(NULL));
a[i] = rand() % (3 + 1 - 1) + 1 ;
printf( " %d\n", a[i]);
}
In your code, ais an integer array, so it cannot hold a string value anyway.
In case, you just want to only print the value, use host in the format string in printf() itself, like
printf( "No. of random selected node = host%d\n", a[i]);
In case, you want the value to be generated and used, in some way, take a buffer and use snprint() to populate the content.
snprint(buf, 8, "host%d", a[i]);
the above will put values like host101, host103 etc. in the buf, as a string. Remember, buf has to be large enough to hold the supplied size (8, in this case.)
Note: Never use magic numbers like 8 in above code, that's just for illustration, use a MACRO definition, at least.

c variable turning into -17918 when incremented

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]);

wrong result in adding huge numbers in c

I want to add some huge numbers which I am gonna input from the keyboard. However I want to input them as a string. I've tried a different way with the ASCII which was written in another answer but it doesn't seem to work. Anyway here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/* ADDING HUGE NUMBERS */
int addHugeNumbers(char *a1,char *a2,char *res){
int i,q,e; // k is the add
int k;
k=0;
i=0;
q=0;
e=strlen(a1);
while (i<e-1) //CHECK IF THE FIRST ONE IS ONLY DIGITS
{
if (isdigit(a1[i])==0) return 0;
else i++;
}
i=0;
q=strlen(a2);
while (i<q-1) //SAME CHECK FOR THE SECOND ONE
{
if (isdigit(a2[i])==0) return 0;
else i++;
}
k=atoi(a1)+atoi(a2);
sprintf(res,"%d",k);
puts(res);
return 1;
}
int main(int argc, char *argv[]) {
char a1[2000], a2[2000],res[2000];
fgets(a1,2000,stdin);
fgets(a2,2000,stdin);
printf("%d",addHugeNumbers(a1,a2,res));
return 0;
}
This code works just fine with small numbers (lets say up to 5-6 digits). But then when it comes to bigger numbers (15-16) it gives me wrong answers.
Try to add 9999999999999999 + 9999999999999999
Rightly said that C has no built-in support for arbitrarily huge numbers.
So if there is really a need to add huge numbers input as strings, then write your own function for summing them up by adding unit digits, tens digits, hundreds digits and so on keeping in mind to accommodate the carry if any.

Convolution in C without Stackoverflow

I'm trying to do a convolution algorithm in C but is stacking on the array of convolution.
#include <stdio.h>
#include <math.h>
#include <stddef.h>
#define convtotal 2590
int main(int argc, char *argv[]) {
int m,n,i,j;
double x[convtotal],h[convtotal];
m=sizeof(x)/sizeof(double);
n=sizeof(h)/sizeof(double);
double aux1[convtotal], aux2[convtotal],conv[convtotal][1];
for (i=0;i<n+m;i++){
if (i<n)
aux1[i]=x[i];
else
aux1[i]=0;
if (i<m)
aux2[i]=h[i];
else
aux2[i]=0;
}
for (i=0;(n+m-1);i++){
conv[i][1]=0;
for (j=0;j<m;j++)
if (i-j+1>0)
conv[i][1]=conv[i][1]+(aux1[j]*aux2[i-j+1]);
}
}
Any suggestions for this problem?
Two problems:
for (i=0;(n+m-1);i++)
You're not limiting i to anything, so the loop doesn't exit when you reach the end of your arrays; it just keeps incrementing i until you hit memory you don't own, at which point you get the segfault. Since conv only goes to m or n, I think you meant to write
for (i = 0; i < n; i++)
Secondly, you declared conv as an Nx1 array, meaning the only legal index in the second dimension may be 0, so the lines
conv[i][1] = 0;
and
conv[i][1]=conv[i][1]+(aux1[j]*aux2[i-j+1]);
should be
conv[i][0] = 0;
and
conv[i][0]=conv[i][0]+(aux1[j]*aux2[i-j+1]);
Not sure why you declared an Nx1 array (seems you could have just declared conv with one dimension), but I may be missing something obvious.
Note that your x and h arrays initially contain random values.
for (i=0;(n+m-1);i++){
conv[i][1]=0;
for (j=0;j<m;j++)
if (i-j+1>0)
conv[i][1]=conv[i][1]+(aux1[j]*aux2[i-j+1]);
}
(n+m-1) infinite loop with constant as a stop condition.
Not actually infinite, runs untill it segfaults.
for (i=0;(n+m-1);i++){
Shouldn't it be i < m+ n - 1?

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