nested for loop value of not initialized - c

I know question sounds dumb, I can't really figure out what is wrong in this code?
void sort(int *arr, int size)
{
int min = 0;
for (int i = 0; i < size - 1; i++)
{
for (int j = i; i < size; j++)
{
if (arr[min] > arr[j])
{
min = j;
}
}
if (min != i)
{
Swap(&arr[i], &arr[min]);
}
}
}
The following code should sort the arr but it is giving segmentation fault.
I ran this code via debugger and it says the value of j at line
for (int j = i; i < size; j++)
something like 3234 (not initialized) and program ends. But j should be 0.
debuger screenshort

In your second for loop, it should be j < size, not i < size.

There are 3 problems in your sort function:
The test in the inner for loop uses i instead of j. j is initialized but the test always succeeds and the loop goes on, letting the code access arr beyond its boundaries, causing undefined behavior.
min should initialized to i inside the outer loop,
j should be initialized to i + 1 is the inner loop (minor).
Here is a corrected version:
void sort(int *arr, int size) {
for (int i = 0; i < size - 1; i++) {
int min = i;
for (int j = i + 1; j < size; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
if (min != i) {
Swap(&arr[i], &arr[min]);
}
}
}

Related

Attempt to arrange array elements in descending sequence (returning garbage values)

I wrote to program in C to attempt to print array elements in descending order. I wrote a nested loop which would find the maximum element of the array and the value of the element would be set to later 0. This process would be repeated for all the elements. However, in the output, I am getting the first 2-3 values as desired but the remaining values are garbage. Any suggestions?
int main() {
int i, j, n, k;
scanf("%d\n", &n);
int a[100], b[100];
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (i = 0; i < n; i++) {
int max = a[i];
for (j = i; j < n; j++) {
if (a[j] > max) {
max = a[j];
b[i] = max;
}
}
for (k = 0; k < n; k++) {
printf("%d", a[k]);
if (a[k] == b[i]) {
a[k] = 0;
}
}
printf("\n");
}
for (i = 0; i < n; i++) {
printf("%d ", b[i]);
}
}
The main issue is that you only set b[i] = max; when you find a new max, but since you initialized max to be a[i] it could happen that it already holds the maximum value. So the if never executes, therefore b[i] is not written and there's garbage value in it. You should move this line from the if after that for loop.
Another issue is that you initialize j with i in this loop. You should initialize it to 0.
The changed part:
for (j = 0; j < n; j++) {
if (a[j] > max) {
max = a[j];
}
}
b[i] = max;

Unsure why does Bubble sort code have a segmentation fault

Hi I'm using gdb to debug my bubble sort code but I don't get why it keeps breaking at if(a[j] < a[j-1]
here is my bubble sort function
void sort(int a[], int n) {
int i, j, nswaps, tmp;
for(i = 0; i < n; i++) {
nswaps = 0;
for(j = 0; j > i; j++) {
if(a[j] < a[j-1]) {
tmp = a[j];
a[j] = a[j-1];
a[j-1] = tmp;
nswaps++;
}
}
if(nswaps == 0) break;
}
}
Please do help me thanks!!
updated code: still has a segmentation fault
void sort(int a[], int n) {
int i, j, nswaps;
for (i = 0; i < n; i++) {
nswaps = 0;
for (j = 1; j > i; j++) {
if (a[j] < a[j-1]) {
int tmp;
tmp = a[j];
a[j] = a[j-1];
a[j-1] = tmp;
nswaps++;
}
}
if (nswaps == 0) break;
}
}
In the first iteration of the outer loop (when value of i is 0), the inner loop becomes an infinite loop, because value of j starts from 0 and keeps increasing. Eventually j becomes large enough for your program to access some unallocated memory, hence causing a segmentation fault.
Also, in the first iteration of the inner loop, value of j is 0, so a[j - 1] will try to access a memory location out of bound for your program.
j > i is false on the first iteration, so if(nswaps == 0) is true and the loops break, no sorting occurs.
Instead of iterating the outside loop n times, iterate n-1 times.
No need to count swaps, a simply boolean is sufficient.
After the first inner loop iteration, the lowest element of the array is found and in place at the end. The next inner loop only needs to iterate to next-last element, etc.
size_t is the Goldilocks type for array indexing, neither too narrow, nor too wide. Better than using int for indexing. Remember that is is an_unsigned type_.
No need to declare a variable until needed.
#include <stdbool.h>
#include <stdlib.h>
void bubble_sort(int a[], size_t n) {
while (n > 1) {
bool swapped = false;
for (size_t j = 1; j < n; j++) {
if (a[j-1] < a[j]) {
int tmp = a[j];
a[j] = a[j - 1];
a[j - 1] = tmp;
swapped = true;
}
}
if (!swapped) {
break;
}
n--;
}
}

counting negative integers in a matrix

i am having error while running this code
negativenoinmatrix.c:10:16: error: subscripted value is neither array nor pointer nor vector
if(z[i][j]<0)
i want to calculate the number of negative integers in a matrix
#include <stdio.h>
int negnumbers(int *z, int n, int m)
{
int count = 0;
int i = 0;
int j = m - 1;
while (j >= 0 && i < n)
{
if (z[i][j] < 0)
{
count += (j + 1);
i += 1;
}
else
j -= -1;
}
return count;
}
int main()
{
int n = 3, m = 4;
int a[n][m];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
scanf("%d", &a[i][j]);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
printf("%d ", a[i][j]);
printf("\n");
}
int val = negnumbers((int *) a, 3, 4);
printf("%d", val);
}
The function needs to accept a pointer to an array, not a pointer to a single item. Change it to
int negnumbers(int n, int m, int z[n][m])
...
int val = negnumbers(3, 4, a);
(Where int z[n][m], as per the rule of "array adjustment", will get changed by the compiler internally to a pointer to the first element, int (*z)[m].)
When you pass a 2-d array to a function, at least the 2nd dimension must be specified. Change to this:
int negnumbers(int z[][4],int n,int m)
You can then use this more straightforward approach to counting the negative numbers:
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (z[i][j] < 0)
count++;
}
}
You are calling a pointer z, and also creating a dynamic matrix out of it. So you need to allocate some memory for it which can be done with:
malloc(z[i][j])
Then after you're done, make sure you deallocate the memory now or else you'll have a memory leak, which you can read more about at Memory Leaks wikipedia.
This is done by calling free(...)
Hope this solves the not an array or pointer error!

array counting sort segmentation fault

Hello i am trying to use counting sort to sort numbers that i read from a file. this is my code:
void CountingSort(int array[], int k, int n)
{
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++)
{
C[i] = 0;
}
for (j = 1; j <= n; j++)
{
C[array[j]] = C[array[j]] + 1;
}
for (i = 1; i <= k; i++)
{
C[i] = C[i] + C[i-1];
}
for (j = 1; j <= n; j++)
{
B[C[array[j]]] = array[j];
C[array[j]] = C[array[j]] - 1;
}
printf("The Sorted array is : ");
for (i = 1; i <= n; i++)
{
printf("%d ", B[i]);
}
}
void max(int array[],int *k,int n){
int i;
printf("n je %d\n",n);
for (i = 0; i < n; i++)
{
if (array[i] > *k) {
*k = array[i];
}
}
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k=0,n,x,z;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
max(array,&k,n);
printf("Max je %d\n",k);
CountingSort(array,k,n);
return 0;
}
i have no errors but when i start my program i get Segmentation fault error. pls help! (dont read this bot is asking me to write some more details but i have none so i just write some random words so i can post my question and hopefully get an answer)
The problem is that your implementation of the counting sort is incorrect: it uses arrays as if they were one-based, while in C they are zero-based.
After carefully going through your loops and fixing all situations where you use a for loop that goes 1..k, inclusive, instead of the correct 0..k-1, the code starts to work fine:
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++){
C[i] = 0;
}
for (j = 0; j < n; j++){
C[array[j]]++;
}
for (i = 1; i <= k; i++){
C[i] += C[i-1];
}
for (j = 0; j < n; j++) {
B[--C[array[j]]] = array[j];
}
printf("The Sorted array is : ");
for (i = 0; i < n; i++) {
printf("%d ", B[i]);
}
Demo.
Note: I modified some of the operations to use C-style compound assignments and increments/decrements, e.g. C[array[j]]++ in place of C[array[j]] = C[array[j]] + 1 etc.
The problem most likely is here
int B[100], C[1000]; // C has space for numbers up to 999
...
for (i = 1; i <= k; i++)
C[i] = C[i] + C[i-1]; // adding up till C[k] == sum(array)
for (j = 0; j < n; j++)
B[C[array[j]]] = array[j]; // B has space up to 99, but C[k] is sum(array)
so you're reserving space for C for a highest value of 999 but in B you're assuming that the sum of all input values is less than 100...
the resolution of your problem is to first probe the input array and get the maximum and the sum of all input values (and minimum if the range may be negative) and allocate space accordingly
edit: you probably meant j < n and not j <= n
Adding to dasblinkenlight's spot-on answer:
Is your input data guaranteed to be in the range [0, 999]? If it isn't, it's obvious that segmentation faults can and will occur. Assume that the maximum value of array is 1000. C is declared as
int C[1000];
which means that C's valid indices are 0, 1, 2, ... 999. But, at some point, you will have the following:
C[array[j]] = ... /* whatever */
where array[j] > 999 so you will be attempting an out-of-bounds memory access. The solution is simple: probe array for its maximum value and use dynamic memory allocation via malloc:
/* assuming k is the maximum value */
int * C = malloc((k + 1) * sizeof(int));
Note: an alternative to this, which would also nullify the need for an initialization loop to make all elements of C equal to 0, would be to use calloc, which dynamically allocates memory set to 0.
// allocate C with elements set to 0
int * C = calloc(k + 1, sizeof(int);
Another important factor is the range of your running indices: you seem to have forgotten that arrays in C are indexed starting from 0. To traverse an array of length K, you would do:
for (i = 0; i < K; ++i)
{
processArray(array[i]);
}
instead of
for (i = 1; i <= K; ++i)
{
processArray(array[i]);
}

Strange Bubble sort behaviour

Can anyone explain why this bubble sort function doesn't work and why I lose numbers in my output? I'm very new to C, so please forgive me if this is something very obvious I have missed.
#include <stdio.h>
#include <stdlib.h>
int bubble(int array[],int length) {
int i, j;
int temp;
for(i = 0; i < (length); ++i) {
for(j = 0; j < (length - 1); ++j) {
if(array[i] > array[i+1]) {
temp = array[i+1];
array[i+1] = array[i];
array[i] = temp;
}
}
}
return 0;
}
int main() {
int array[] = {12,234,3452,5643,0};
int i;
int length;
length = (sizeof(array)/sizeof(int));
printf("Size of array = %d\n", length);
bubble(array, length);
for (i = 0; i < (length); ++i) {
printf("%d\n", array[i]);
}
return 0;
}
Output
Size of array = 5
12
234
3452
0
0
In your inner loop, you don't use j at all. Double check your logic.
Also note that array[i+1] goes beyond the array boundary.
for (i = 0; i < (length-1); ++i) {
for (j = 0; j < (length-i-1); ++j) {
if(array[j] > array[j+1]) {
temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
In a bubble sort you only use the inner loop variable.
Another thing, the inner loop goes from 0 to i if I remember well; but I think that's just an optimisation (as the tail is remains sorted in each step).
Try to run step by step your code with paper and pencil. That always works.
for (i = 0; i < (length); i++) {
for (j = 1; j < (length-i); j++) {
if(array[j-1] > array[j]) {
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
}

Resources