0

I have to create functions for print array, fill array witn descending numbers.

I created functions for printing array and creating descending array.But I faced with a problem. If I use my own function printArray() it prints something unclear. Where is the problem, what i do wrong? Please, help.

Here is the code in C. value - is value of array

Function for printing array:

void printArray (int arr[]){
   int i;
   printf("\n");
     for(i = 0; i < value; i ++)
       printf("%3d ", arr[i]);
}

Function for creating descending array:

int createDescendingArray(int a[])
{
    int i;
    printf("\nDescending array is created.\n");
    for (i = value; i > 0; i--) {   
        a[i] = i;
    }
  printArray(a); // print of created array
}

Main function:

int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}

enter image description here

However when I don't use my print function in function createDescendingArray() and print it in Main funktion with standart method like this:

{int i;
 for(i = 0; i < value; i++)
 {
 a[i]=i;
 printf("%3d", a[i]);
 }
}

It shows descending array as ascending (look at the picture) How it works?

enter image description here

  • 2
    Please don't post pictures of text but post text as text. – Jabberwocky Oct 26 '21 at 15:28
  • 3
    Your code is incomplete, please post a [mcve]. Also reads this: [ask] – Jabberwocky Oct 26 '21 at 15:28
  • 1
    Look closely at `for(i = 0; i < value; i ++)` and at `for (i = value; i > 0; i--)` – Jabberwocky Oct 26 '21 at 15:30
  • 2
    Oh: and `arr1[value] = createDescendingArray (arr1);` is wrong. Just call `createDescendingArray (arr1);` and transform `int createDescendingArray(int a[])` into `createDescendingArray(int a[])` – Jabberwocky Oct 26 '21 at 15:33
  • 1
    I don't know what compiler you are using but you should turn on warnings and pay attention to them. For gcc, you should be compiling with `-Wall -Wextra`. – David Conrad Oct 26 '21 at 15:38
  • 2
    one problem that hasn't been explicitly stated yet .. if you're declaring the array as `int array[value];` , then that contains values in the range `[0, value-1]`, and addressing `array[value]` is out of bounds. This is what happens in the first iteration of `for (i = value; i > 0; i--) { a[i] = i; ... }` when `i == value`. And with the `i > 0` condition you never reach the first index of the array. – yano Oct 26 '21 at 15:40
  • 1
    In `createDescendingArray`, you want `for (i = value - 1; i >= 0; i--)` – Craig Estey Oct 26 '21 at 16:02

2 Answers2

1

You have been using a variable named value in your function which prints array, without initializing it, hence the garbage value.

you should initialize it in the function or pass its start value as an argument to the function.

#include <stdio.h>
#include <stdlib.h>

void printArray(int *arr, int length)
{
    int i;
    printf("\n");
    for (i = 0; i < length; i++)
    {
        printf("%3d ", arr[i]);
    }
}

int *createDescendingArray(const int length)
{
    if (length == 0)
        return NULL;
    int *a = malloc(length * sizeof(int));
    ;
    printf("\nDescending array is created.\n");
    for (int i = length-1; i >= 0; i--)
    {
        a[i] = i;
    }
    printArray(a, length); // print of created array
    return a;
}

int main()
{
    int *a = createDescendingArray(20);
    printArray(a, 20);
    return 0;
}

these changes should most probably do the trick but again, there is no initialization of value in the function that creates array as well

EDIT: stop creation of array if length is 0

EDIT2: fixed code to consider 0 as an element

EDIT3: Fixed code with suggestion from @CraigEstey in comments, tested and working

EDIT4: fixed for loop and removed cast on mallock

Rohit Patil
  • 162
  • 8
  • 3
    If `value` is the length of the array then when `i = value` the line `a[i] = i;` invokes undefined behavior by writing beyond the length of the array, and the first element of the array will never be set because the loop stops before `i` is zero due to the loop condition being `i > 0`, so, no, this definitely will not do the trick. – David Conrad Oct 26 '21 at 15:40
  • well as i said in the end, we dont know what value is as it has not been initialized in the provided code. But what you said @DavidConrad is absolutely right, if `value` is `0` then the array will not be made, an edge condition due to insufficient information :). – Rohit Patil Oct 26 '21 at 16:13
  • Repeating my top comment: _In createDescendingArray, you want_ `for (i = value - 1; i >= 0; i--)` You should fix your example code here – Craig Estey Oct 26 '21 at 16:23
  • @CraigEstey, i am taking in length as an argument instead of value , so value-1 in my case will lead to a condition where the array will not be created. although, fixed my code for including 0 as an element in the resultant array. – Rohit Patil Oct 26 '21 at 16:40
  • 1
    No! Your code is _still_ wrong. If an array has a length/count of (e.g.) `length`, the last addressable element is `arr[length - 1]`. Thus, `i = length;` is UB and needs to be `i = length - 1;` Note that if `length` is 1, then `for (i = length - 1; i >= 0; --i)` will fill exactly one element--what you want. If the count <= 0, _no_ elements should be filled – Craig Estey Oct 26 '21 at 18:08
  • BTW, in `createDescendingArray`, doing `return -1;` won't even compile – Craig Estey Oct 26 '21 at 18:17
  • 1
    And, the question is tagged, `c` and _not_ `c++`, doing `new` is just wrong. – Craig Estey Oct 26 '21 at 18:22
  • @CraigEstey, apologies for all the mistakes on my side, didn't see the code was meant to be `c` and not `c++`. Fixed it to use mallock and with your suggetion too. Please let me know if there is a mistake. – Rohit Patil Oct 27 '21 at 09:44
  • The `for` loop is _still_ wrong!!! Also, see: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Craig Estey Oct 27 '21 at 15:02
  • oh man, fixed it but didnt save :( EDIT:@CraigEstey Please check now – Rohit Patil Oct 27 '21 at 15:19
  • Thank you very much, for your help! i found a solution of this trouble! I'm so sorry, that i wrote so 'bad' question. Variable value is: #define value 4 - i use it as value of arrays, so it makes my arrays with equal length. – Natalia Ugolnikova Oct 27 '21 at 17:17
  • Yeah well now, if you use the solution above, need to just define the length of the array you want, instead of the largest value. – Rohit Patil Oct 28 '21 at 08:09
0

The function

int createDescendingArray(int a[])
{
    int i;
    printf("\nDescending array is created.\n");
    for (i = value; i > 0; i--) {   
        a[i] = i;
    }
    printArray(a); // print of created array
}

is wrong.

According to the output in your question, it seems that you have defined value as 4 (you are not showing us the code with the definition). In that case, your code for the mentioned function is equivalent to the following:

int createDescendingArray(int a[])
{
    printf("\nDescending array is created.\n");

    a[4] = 4;
    a[3] = 3;
    a[2] = 2;
    a[1] = 1;

    printArray(a); // print of created array
}

I did nothing else to the code than unroll the loop.

Since the array a has a size of 4 elements, valid indices are from 0 to 3. Therefore, by writing to a[4], you are writing to the array out of bounds, causing undefined behavior.

If you had written

for (i = value - 1; i >= 0; i--)

instead of

for (i = value; i > 0; i--)

then the unrolled loop would be:

    a[3] = 3;
    a[2] = 2;
    a[1] = 1;
    a[0] = 0;

This is better, because now we have fixed the undefined behavior; you are no longer writing to the array out of bounds. However, this is still not what you want. If you want descending output, your unrolled loop must look like this instead:

    a[0] = 3;
    a[1] = 2;
    a[2] = 1;
    a[3] = 0;

This can be accomplished by changing your function to the following:

int createDescendingArray(int a[])
{
    int i;

    printf( "\nDescending array is created.\n" );

    for ( i = 0; i < value; i++ ) {   
        a[i] = value - i - 1;
    }

    printArray(a); // print of created array
}

Here is a small test program:

#include <stdio.h>

//NOTE: It is customary for constants to be written upper-case,
//not lower-case, so the line below should normally not be used.
#define value 4

void printArray (int arr[]) {
   int i;

   printf( "\n" );

   for( i = 0; i < value; i++ )
       printf("%3d ", arr[i]);
}

int createDescendingArray(int a[])
{
    int i;

    printf( "\nDescending array is created.\n" );

    for ( i = 0; i < value; i++ ) {   
        a[i] = value - i - 1;
    }

    printArray(a); // print of created array
}

int main( void )
{
    int array[value];
    createDescendingArray( array );
}

The output is:


Descending array is created.

  3   2   1   0 

In this test program, I took over most of your other code, but I did not take over the function main, because it was also causing undefined behavior:

int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}

In the line

arr1[value] = createDescendingArray (arr1);

you are assigning the return value of the function to a variable, although the function did not return a value. This causes undefined behavior. You may want to consider changing the return type to void in the function declaration, if it does not return a value.

Also, even if the function did return a value, arr1[value] would be writing to the array out of bounds, as valid indices are from 0 to value - 1.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39