I have a random number generator feeding numbers into an array, but when I print out the table, the last line is always a set of values out of the boundaries that I defined in the following function:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int temp[22];
int n;
for(n=0; n<23; n++){
temp[n] = rand()%(100 + 1 - 60) + 60;
printf("%d , %d \n", n, temp[n]);
}
return 0;
Ive created something of this nature before, but now its acting up, I just dont know where.
You are accessing the array outside the bounds which is undefined behaviour.
Instead make use of sizeof operator to avoid such problems:
for(n = 0; n < sizeof temp/sizeof temp[0]; n++)
But note that if temp were to be an malloc'ed pointer (int *temp = malloc(23 * sizeof *temp);) then sizeof wouldn't work.
Your array is being accessed outside of its bounds.
int temp[22];
This declaration assigns 22 indices to temp, temp[0] is the first
value and temp[21] is the last value you can access in your array. Counting 0, from 0..21 = we have 22 values
Your for loop is incorrect:
for(n=0; n<23; n++)
This will make the program attempt to access temp[22], which doesn't exist. You need to change it to:
for(n=0; n<22; n++)
Furthermore:
return 0; needs to be inside and at the end of your main() function. It's possibly a typo, but you're missing a closing brace } in your main() function, at least how you posted it.
Related
i want to sort a string using counting sort but instead of a sorted string some integer values are displayed with a warning iteration 254u invokes undefined behavior pointing at the expression c[i]+=c[i-1] even though the iterations doesn't seem to exceed the signed int limit
the code is
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define range 255
void count_sort(char arr[],int n)
{
int c[range];
int i;
memset(c,0,sizeof(c));
char b[strlen(arr)];
for(i=0;i<n;i++)
{
++c[arr[i]];
}
for(i=1;i<=range;++i)
{
c[i]+=c[i-1];
}
for(i=n-1;i>=0;--i)
{
b[c[arr[i]]-1]=arr[i];
--c[arr[i]];
}
for(i=0;i<n;i++)
{
arr[i]=b[i];
}
}
void print(char arr[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
}
int main()
{
char arr[]="november";
int n=sizeof(arr)/sizeof(arr[0]);
count_sort(arr,n);
print(arr,n);
return 0;
}
what changes are required to make the code run correctly
I checked you here link. The code is correct except for the lines below
(1) printf("%d ",arr[i]);
Change this line to the following since you are printing characters and not integers.
printf("%c ",arr[i]);
If you keep %d then you are casting the char to an integer, and you'll get the ascii value. So for %d specifier, you will get a sorted array of integer values which are ascii values for the corresponding characters.
(2) int c[range];
Change the line to the following
int c[range+1];
Now in your second for loop, it will not exceed the bounds of the array c and you will not get the undefined behavior.
Hope this will help you.
Here are some points that I'd like to share:
You're using %d as format specifier in printf() in print function so change that to %c like this:
printf("%c ", arr[i]);
If your string is properly \0 terminated and you can do without printing space between characters then you can directly use printf() with %s it:
printf("%s", arr);
You don't need the custom print() function in this case.
This loop
for ( int i = 1; i <= range; ++i ) // <== out-of-bounds
{
c[i] += c[i-1];
}
is causing out-of-bounds access resulting in Undefined Behavior. As range represents 255 but the loop condition is i <= range whereas it should be i < range to keep the iterations in the valid range i.e. 0-254.
You are calculating the length of the string like this:
int n = sizeof(arr) / sizeof(arr[0]);
sizeof also calculates the terminating '\0' character so the length of the string will be:
sizeof( arr ) = 9
sizeof( arr[0] ) = 1
n = 9 / 1 = 9
But, the length of the string november is 8. strlen() would be a better choice here.
int n = strlen( arr );
Or,
int n = sizeof( arr ) - 1; // don't include `\0`
In the count_sort function, you're declaring the arrayc like this:
int c[range];
And, then using memset to set it. You could initialize it like this:
int c[range] = {0};
More on memset here.
The array b is declared like this:
char b[strlen(arr)];
^^^^^^^^^^^
But, you already have n, use that. You don't need to calculate the length again.
You should use %c instead of %d to print the characters.
You should also use for( i=1; i < range; i++ ), i <= range will give fault as last index of array is range-1.
there are some problem in you code first you are using wrong format specifier for printing chars.You have to use %c instead of %d in your printing function.
also you should remove = from this loop for(i=1;i<=range;++i) , otherwise you will pass boundaries of array c which will lead to undefined behavior , or if you need that element you should declare c[range+1] instead of c[range].
also note that in your sorting since ASCII code of \0 is smallest , it will become first element of your array and so neither b nor arr will be terminated.
I suggest this loop:
for (i = n - 2; i >= 0; --i)
{
b[c[arr[i]] - 2] = arr[i];
--c[arr[i]];
}
b[n-1] = '\0';
I was given the assignment of writing a C code which contains a function, which when passed through an array of length n returns a pointer to the array’s largest element. In order to make it easy for us, the length n was set to 10.
I wrote the code below and compiled it and it didn't show any error. Then, I ran this code and it asked for the 10 inputs for the array, but instead of returning the pointer with the largest element, it read segmentation fault 11.
I am new to pointers, and so could not figure out what exactly went wrong. Any help will be greatly appreciated.
#include<stdio.h>
#define N 10
int *find_largest(int a[], int n)
{
int i;
int *max;
*max = a[0];
for(i = 1; i < n; i++)
{
if(a[i] > *max)
*max = a[i];
}
return max;
// this function returns the pointer with the max. value
}
int main(void)
{
int b[N], i;
int *p;
printf("Enter %d numbers: ", N);
for(i = 0; i < N; i++)
scanf("%d", &b[i]);
//scans all the inputs
p = find_largest(b, N);
//p gets assigned the value of the max valued pointer
printf("largest element: %d", *p);
return 0;
}
Edit- After looking at the wonderful advices given, I modified my code a bit. I changed *max=a[0] to max= &a[0], and *max=a[i] to max=&a[i]. Now, the code runs without any error, but instead of returning the pointer with the largest value, it returns the largest input instead.
In this line, you write to the place the uninitialised ponter is pointing to.
*max = a[0];
This causes undefined behaviour (or "UB", reading up on it is worth the time) and to be strictly avoided; among other reasons because it is a very likely reason for segfaults.
What you probably want to do is to write the address of the first element into the pointer.
max = &a[0];
Later you write the place the pointer is pointing to, updating it to the max value you have found.
*max = a[i];
Guessing from the rest of your code, you probably want to just keep the address of the max element, so that you can return its address as it is in the input array, without changing the values in the input array (which your currently do, and it seems unlikely that you intend to...).
max = &a[i];
Referring to your comment (that the value is returned, not the pointer):
For returning a pointer (not a value), make sure that you
return max; // the pointer, not the value it is pointing to
Which is what you actually do in the currently shown code version (possibly before an edit...).
Do not return *max; that would return the value.
If by "return" you mean "print", then you need to change the
printf("largest element: %d", *p);
Use p instead of *p and change the format specifier accordingly.
You probably want "largest element at address: %p". (Compare http://en.cppreference.com/w/c/io/fprintf )
printf("largest element at address: %p", p);
int *max;
*max = a[0];
This is UB (undefined behavior) since max is not pointing to valid memory and you try to dereference it.
max = &a[0];
Moreover your logic to find the max is wrong. Why do you reset it every time to 0th element. It should be something like.
for(i = 1; i < n; i++)
{
if(a[i] > *max)
max = &a[i];
}
I'm tasked with writing a function that will identify all the even numbers in an sample array {10,2,9,3,1,98,8] and place them in an array called EvenNumbers. I have to allow the function so that it works with different combinations of numbers in the array not just the numbers in the sample array above.
I'm wondering is there any way to add numbers to an array that could be different every time? How would I extract the even numbers an place them into an array? Also
for the even array size its giving me an error that the expression must have a constant value but when I use const int it still gives me that error.
Here is the full question.
"Using the array of sample values {10,2,9,3,1,98,8}, write a function that will identify all the even numbers in an array and place it in an array called EvenNumbers. The function must work in all cases, not just in the case of the array shown. Assume that the array size is always available through a global constant called MAX"
Here is what I have so far. I've no idea how I will extract the even numbers from a for loop and place them in an array. I also dont know what the "expression must have a constant value" is about?
#include <stdio.h>
#include <stdlib.h>
void EvenNumber(int Array[], int size);
int main()
{
int array[7] = { 10,2,9,3,1,98,8 };
EvenNumber(array, 7);
}
void EvenNumber(int Array[], int size)
{
int i;
int EvenArraySize;
for (i = 0; i < size; i++)
{
if (Array[i] % 2 == 0)
{
EvenArraySize++;
}
}
int Even[EvenArraySize];
}
The right way to go is to use malloc to allocate just the right amount of memory.
Count the number of even numbers
Allocate the space needed to store them
Copy even numbers in this space
Do whatever you want with these numbers
Free the allocated space
Snippet:
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
int
main()
{
int array[] = {10,2,9,3,1,98,8};
int *even_numbers;
int i, nb_even_numbers;
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
nb_even_numbers++;
}
even_numbers = malloc(sizeof(int) * nb_even_numbers);
if (!even_numbers)
{
perror("malloc");
return 1;
}
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
even_numbers[nb_even_numbers++] = array[i];
}
/* do your stuff here */
free(even_numbers);
return 0;
}
First, you can never return a statically declared array from a function (even though you don't explicitly try, your Even array is destroyed when EvenNumber returns) Why? The function stack frame for EvenNumber is released for reuse on return and any locally declared arrays are no longer valid.
You either need to pass a second array as a parameter to EvenNumber, or you can dynamically allocate storage for Even in EvenNumber (with, e.g. malloc or calloc or realloc) and return a pointer to the beginning of the array. (you must also have some way to return the size or use a constant for a max size).
There is no need to use % (modulo) to test whether a number is odd/even. All you need to do is look at bit-0 (little endian). If it is 0, then the number is odd, if it is 1, then its even. Much more efficient than calling modulo which incorporates division.
Finally, main is type int and therefore returns a value.
Putting those pieces together, you can do something simple like the following:
#include <stdio.h>
#include <stdlib.h>
void EvenNumber (int *array, int *even, int size, int *esize);
int main (void)
{
int array[] = { 10,2,9,3,1,98,8 },
i, n = sizeof array / sizeof *array,
even[n], /* a VLA of the same size as array is fine here */
esize = 0;
EvenNumber (array, even, n, &esize);
printf ("array: ");
for (i = 0; i < n; i++)
printf (" %2d", array[i]);
printf ("\neven : ");
for (i = 0; i < esize; i++)
printf (" %2d", even[i]);
putchar ('\n');
return 0;
}
void EvenNumber (int *array, int *even, int size, int *esize)
{
int i;
for (i = 0; i < size; i++)
if ((array[i] & 1) == 0) /* simply looking at bit-0 is all you need */
even[(*esize)++] = array[i];
}
Note: esize is passed as a pointer to EvenNumber and updated within the function so that the number of elements in even are available back in the calling function (main() here).
Example Use/Output
$ ./bin/arrayeven
array: 10 2 9 3 1 98 8
even : 10 2 98 8
Let me know if you have any further questions.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
void check(int n, int arr[]);
int arr[] = {1, 2, 3, 4};
int i;
check(4, arr);
for (i = 0; i < 4; i++) {
printf("%d\n", arr[i]);
}
return 0;
}
void check(int n, int arr[]) {
int i = 0;
int *p = 0;
while (i++ < n)
p = &arr[i];
*p = 0;
}
I need an explanation for the output.
The original question I was asked, and the expected multiple-choice answers, are:
Please post your actual code, not what you intended to type. Actually copy-paste your real code.
Because you typed it in wrong.
You either put extra {} in here:
while(i++ < n) {
p = &arr[i];
*p = 0;
}
or you used a comma instead of a semicolon:
while(i++ < n)
p = &arr[i],
*p = 0;
and so the assignment to zero ran every time.
Edit to add: Yep, you put extra {} which the original question didn't have. So in your code, the "*p = 0" executes every time round the while loop, whereas the original question the "*p = 0" only executes once and clobbers some random data that is one past the end of the array.
(By the way, the answer to the original question is actually "it is undefined behaviour; the program doesn't necessarily print anything. Valid behaviours include printing 1 2 3 4, printing 42 42 42 42, crashing, and formatting your hard drive.")
I'm not sure what choices you're talking about, however the cause of your output is here:
int i=0;
int *p=0
while(i++<n)
{
p=&arr[i];
*p=0;
}
Variable 'i' starts at 0 but you increment it before entering the loop so the first index of the array is ignored. You then set a pointer to array index 'i' and then immediately dereference the pointer and set the value to 0;
Because of this any array you pass will always retain its first value whilst every other value will be zero.
if you want to include the first index of the array you'd be much better off doing:
for (int i = 0; i < n; ++i)
{
// stuff
}
With this, 'i' is not incremented until after the code between the braces has been executed.
In check(), i gets incremented after the comparison, but before the first statement inside. So the zero (first) element of the array is never set to 0, like the rest are. arr's 1 stays 1, and 2, 3, & 4 each become 0.
EDIT:
The OP code has changed since the version I discussed. It's a whole new problem now.
Some things you should know.
First:
you should declare your functions if you declare/define them after main.
Second:
when you declare an Array, the array starts from 0 to n and not from 1 to n.
So, if you declare int arr = {1,2,3,4} then you have arr[0],1,2,3 and not arr[1],2,3,4.
Third:
you should avoid code like:
while (i++ < n) {
p = &arr[i];
*p = 0;
}
And use:
while (i < n) {
p = &arr[i];
*p = 0;
i++;
}
Fourth:
What exactly did you expected from this:
int *p = 0;
Anyway, you just try to access a memory location that not belong to you.
This question already has answers here:
Weird behavior when printing array in C?
(5 answers)
Closed 9 years ago.
Can anyone please explain the output for the following program? I get an infinite loop if used a[i] = 0; and a segfault when I used a[i] = i; and also the i ranges between 0 - 9 when used a[i] = 0; whereas it goes to 39 when used a[i] = i; before giving a segfault.
#include<stdio.h>
#include<stdlib.h>
int mult(int a, int b);
int main()
{
int a[10];
int i = 0;
for(i=0; i < sizeof(a); i++)
{
a[i] = i;
printf("a[i]=%d i=%d\n", a[i], i);
}
return 0;
}
When you apply the sizeof operator to an array type, the result is the total number of bytes in the array, i.e, sizeof(a) determines the number of bytes in a which is not the number of elements in the array in this case. Use sizeof(a)/sizeof(a[0]) to get number of elements in the array a.
Replace
for(i=0;i<sizeof(a);i++)
with
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
Also, no need to initialize i twice.
You probably want to change this line:
for(i=0;i<sizeof(a);i++)
to this:
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
Note:
sizeof(a) gives the number of bytes in a[].
sizeof(a)/sizeof(a[0]) gives the number of elements in a[].
sizeof doesn't do what you think it does. It's returning the number of bytes occupied by the entire array.
You want the numeric length of the array, not the byte size.
Try something like this:
const int array_size = 10;
int a[array_size];
for (int i = 0; i < array_size; i++) {
a[i] = i;
printf("a[%d] = %d\n", i, a[i])
}
If you want to know how far to loop, without storing it in a separate const, use sizeof(a)/sizeof(a[0])