2

Following is the code from www.tutorialspoint.com, where i am learning basics of algorithm & data structure. This tutorial code gives an ex. of insertion operation on array.

    #include <stdio.h>
    main() {
       int LA[] = {1,3,5,7,8};
       int item = 10, k = 3, n = 5;
       int i = 0, j = n;

       printf("The original array elements are :\n");

       for(i = 0; i<n; i++) {
          printf("LA[%d] = %d \n", i, LA[i]);
       }

       n = n + 1;

       while( j >= k){
          LA[j+1] = LA[j];
          j = j - 1;
       }

       LA[k] = item;

       printf("The array elements after insertion :\n");

       for(i = 0; i<n; i++) {
          printf("LA[%d] = %d \n", i, LA[i]);
       }
    }

I understand the code that it adds new item at give value of k as index of array. And it runs fine without any error when compiled & runs. What confuses me is logic of line LA[j+1] = LA[j] in while loop.

My understanding is that in c you have to declare the size of array. But in ex. code int LA[] = {1,3,5,7,8}; bracket [ ] is empty. So i am not sure if it's a fixed size or more elements can be added to array.

Now j is given the value of n which is 5(length of array). Array declaration has 5 element, and index of array is 0 to 4.

(On first iteration of while loop)So LA[j + 1] is LA[5 + 1] is LA[6]. Now array has only 5 elements indexed 0 to 4. So according to me even after assuming that more element can be added to array, how can it assign value of LA[j] which is 5 to LA[j + 1]. it's saying LA[6] = LA[5] but there is nothing at index 5 as last index is 4.

I have tried to search on google but I am not sure what to search except the code or part of code. And searching with code wasn't helpful.

Please help me understand. Thank You.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
JVL Jewels
  • 23
  • 2
  • 2
    When you don't understand some code you can always try stepping through it with a debugger - this can help to make the logic a lot clearer. – Paul R Jun 24 '16 at 10:34
  • Does www.tutorialspoint.com really provide this as an example of good code or is it an example of very bad code that you are supposed to fix? If this code is provided as an example of good code, I'll suggest that find another place to learn `c`. – Support Ukraine Jun 24 '16 at 11:33
  • I am learning algorithm & data structure. The code provided by them runs and does add one more element to array. I have compiled and ran the code and its working. I don't know how to debug c code yet. will google and try – JVL Jewels Jun 24 '16 at 12:35
  • It only happens to work @JVLJewels. This code invokes undefined behaviour. Make sure you read the answers and accept one. – gsamaras Jun 24 '16 at 12:40

2 Answers2

3
int LA[] = {1,3,5,7,8};

is equivalent to:

int LA[5] = {1,3,5,7,8};

The empty bracket just tells the compiler to automatically set the number of elements as the size of the array.


Yes, you are right, L[6] is out of bounds access, since L has size of 5. So, as you nicely said, the indices are in [0, 4], so L[5] is also out of bounds!

This code is wrong!


Read more on Undefined Behaviour: Undefined, unspecified and implementation-defined behavior

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Yes. And that is the reason of my confusion. But why does the code gives the correct output if it is out of bound? That's what i am trying to figure out. Thank you for giving your time to answer my question. – JVL Jewels Jun 24 '16 at 12:41
  • @JVLJewels undefined behaviour means that the program may or may not work as you expect it would. For example it may work as you expect in your machine today, but not tomorrow. In my machine it may doesn't work as you expect today. I have edited my answer, hope that helps! – gsamaras Jun 24 '16 at 12:50
1

First of all it is a very bad code that is written by a very weak programmer and has undefined behaviour.

For example the array LA

int LA[] = {1,3,5,7,8};

has only 5 elements.

However in these loops

   while( j >= k){
      LA[j+1] = LA[j];
      ^^^^^^^
      j = j - 1;
   }

and

   for(i = 0; i<n; i++) {
              ^^^^ n is already set to 6
      printf("LA[%d] = %d \n", i, LA[i]);
   }

there are attempts to write to the memory beyond the array. Also there are some magic values as for example n = 5. It would be much better to write at least

n = sizeof( LA ) / sizeof( *LA )

Take into account that function main without parameters in C should be declared like

int main( void )

The program can look for example the following way

#include <stdio.h>

int main( void ) 
{
    int a[] = { 1, 3, 5, 7, 9 };
    const size_t N = sizeof( a ) / sizeof( *a );

    while ( 1 )
    {
        printf( "The original array elements are:" );
        for ( size_t i = 0; i < N; i++ ) printf( " %d", a[i] );
        printf( "\n" );

        printf( "\nEnter a number to insert in the array (0 - exit): " );
        int value;

        if ( scanf( "%d", &value ) != 1 || value == 0 ) break;

        printf( "Enter a position in the array where to insert: " );
        size_t pos;

        if ( scanf( "%zu", &pos ) != 1 ) break;

        size_t j = N;

        if ( pos < N )
        {
            while ( --j != pos ) a[j] = a[j-1];
            a[j] = value;
        }           

        printf( "\nThe array elements after insertion:");

        for ( size_t i = 0; i < N; i++ ) printf( " %d", a[i] );
        printf( "\n\n" );
    }

    return 0;
}

Its output might look like

The original array elements are: 1 3 5 7 9

Enter a number to insert in the array (0 - exit): 2
Enter a position in the array where to insert: 1

The array elements after insertion: 1 2 3 5 7

The original array elements are: 1 2 3 5 7

Enter a number to insert in the array (0 - exit): 6
Enter a position in the array where to insert: 4

The array elements after insertion: 1 2 3 5 6

The original array elements are: 1 2 3 5 6

Enter a number to insert in the array (0 - exit): 0

The logic behind the algorithm is simple. If you have an array with N elements and want to insert a value in the position pos that less than N then you need to move all elements to the right starting from the position pos and write the new value in the element with index pos. The right most element of the original array will be lost because it will be overwritten by the preceding element. The program output shows this result.

As you correctly pointed out yourself the valid range of indices for the array defined as having 5 elements used in the program is [0, 4].

When an array is declared without its dimension as in this example

int a[] = { 1, 3, 5, 7, 9 };

then the compiler determinates its dimension from the number of initializers. Thus the above declaration is equivalent to

int a[5] = { 1, 3, 5, 7, 9 };
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you for giving you time to answer my question. You answer is insightful and also gives more knowledge of c programming. Do you know why does it run and give correct output when it's out of bound? – JVL Jewels Jun 24 '16 at 12:46
  • @JVLJewels As the behavior is undefined then the result can be any including the correct output.:) That is it means that overwriting the memory beyond the array did not prevent to output it.:) – Vlad from Moscow Jun 24 '16 at 12:48