Link to home
Start Free TrialLog in
Avatar of Sourodip Kundu
Sourodip Kundu

asked on

Error occurred in the output of insertion and deletion operation with an array in data structure

I am a newbie to data structure I have done the following code for `Insertion` and `Deletion` operation with an array, it runs without error but there is a runtime error plz help me to find out the error.

 
    #include <stdio.h>
    
    #define MAX 5
    
    
        void insert(int *,int pos, int num);
        void del(int *,int pos);
        void display(int *);
       
    
            int main()
            {
    
                int arr[5];
    
    
    
                /*Start of array insertion function*/
                    insert(arr,1,11);
                    insert(arr,2,12);
                    insert(arr,3,13);
                    insert(arr,4,14);
                    insert(arr,5,15);
                /*End of array insertion function*/
    
                printf("Elements of Array:\n"); /*printing aray elements after insertion*/
                    display(arr); /*display funtion called for printing array elements*/
    
                /*Start of deletion of array function*/
                    del(arr,5);
                    del(arr,2);
                /*End of deletion of array function*/
    
                printf("After deletion of array:\n");/*printing array elements after deletion*/
                    display(arr);/*display function called for printing array element*/
    
               
    
    
                return 0;
    
            }
    
            /*inserts an element num at given position pos*/
                void insert(int *arr, int pos, int num) {
    
                /*shifts element to right*/
                    int i;
                        for (i = MAX - 1; i >= pos; i--) {
                    /*swapping*/
                        arr[i] = arr[i - 1];
                        arr[i]=num;
                     }
    
            }
    
            /*deletes an element from the given position pos */
                void del(int *arr, int pos){
                /*skip to the desired position*/
                    int i;
                        for(i=pos;i<MAX;i++){
                            arr[i-1]=arr[i];
                            arr[i-1]=0;
    
                    }
    
            }
    
            /*display the content of the array*/
                void display(int *arr){
                /*traverse the entire array*/
                int i;
                    for(i=0;i<MAX;i++){
                        printf("%d\t",arr[i]);
                        printf("\n");
    
                    }
            }

Open in new window

The following output is showing-

   Elements of Array:
    -13136      
    11      
    12      
    13      
    14      
    After deletion of array:
    -13136      
    0      
    0      
    0      
    14      
   
    Process finished with exit code 0

But my expected output is-

    Elements of Array:
   
    11 12 13 14 15
   
    After deletion:
   
    11 0 13 14 0

What's the problem with my code why the wrong output showing for `Insertion` and `Deletion`operation?plz explain me in detail what is the problem
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
to add to Zoppo's comment

/*swapping*/

arr[i] = arr[i - 1];
arr[i]=num;

the code in insert function (which was called 'add' by Zoppo) is not swapping as you wrote in the comment.  

you were assigning num value to arr[i] (thus overwriting the shifted value of arr[i-1]) for all i between pos and MAX-1

this means after your first call of insert  'insert(arr,1,11);' the array contains { garbage, 11, 11, 11, 11 }  because the loop runs from MAX-1 == 4 to pos == 1 and assigns num == 11 to all the elements. the arr[0] was not set and is some arbitrary value as you didn't initialize the array.

so you should do in main

int arr[MAX] = { 0 };   /* all values are zero now */

Open in new window


and insert function is

        /*pass the size of the array as argument*/
        void insert(int *arr, int siz, int pos, int num) 
        {
             int i = 0;  /* always initialize variables */
             if (pos < 0 || pos >= siz)
                     return;   /* wrong insert */

            /* we shift the left item to all items between pos + 1 and siz-2  the old value at siz-1 was lost */
            /* we must do that with a backwards loop */
            /* note the greater operator we don't need to assign a value to arr[pos] */
            for (i = siz - 1; i > pos; i--)  
            {
                  arr[]i ] = arr[]i-1];  
            }
            /* arr[]i] = num; also would be correct as i == pos after the loop */
            arr[pos]=num;
        }   

Open in new window


you would call the above insert function like

insert(arr, MAX, 0, 10);

Open in new window


note, that 10 was inserted at position 0 of the array. see comment of Zoppo regarding zero-based indices.

Sara
I'll add that defining a symbol for array size is a bad practice:

First, this is error prone.
Second, it isn't strongly typed.
Third, it is global scope.
Fourth, since the compiler replace the symbol with the value, this can lead to nasty surprises.
I'll add that defining a symbol for array size is a bad practice:
Fabrice, you should be more detailled and give better reasoning because your statement isn't right at least not in that generality.

- defining a symbol for array size

  you probably mean a preprocessor macro like MAX which was defined with #define.
  i can't see anything bad with defining this macro in a local source beside that MAX obviously is a poor name and
  can lead to errors because of its poorness and ambuigity.

actually, if you have to define a fixed-sized array, the size must be a constant. so you have 4 choices

define a constant  by either
   
     #define MAX_ARRSIZ     5
     const int MAX_ARRSIZ = 5;
     enum { MAX_ARRSIZ = 5 };
 
or use the 5 as array size.

i think we agree the last is worse when more than one array was defined with the same size or if the array size needs to get passed to a function.

so which of the first three choices is the best?

i will check it against your criteria:

1. this is error prone.

if  a macro is defined in a cpp file, the precompiler will replace the macro by the integer. so you easily can see what the array size is, and a you don't have a variable which can be corrupted somehow or can be used somewhere else. actually, it is a very safe choice beside you were using a bad name. for macro definiions in header files things are shlightly different (especially if the macor values are computed from other macros), but i can't see any higher error risks as for a constant or an enum which all can be defined in headers as well. for all, you can't use the same name twice as it is for variables what reduces error risks like if you have CLASSA::MAX_ARRSIZ and CLASSB::MAXARRSIZ-

2. Second, it isn't strongly typed.
actually a macro isnt type'd at all but as it was replaced by the literal when compiling you immmediately get a type check by the compiler.

note, enum constants are not typed either. they will replaced by the compiler same as the precompiler would replace the macros. constant variables are typed but they also will be replaced beside you were using their address by using a pointer or reference of the constant variable.

3. Third, it is global scope

global scope isn't  a bad thing per se. each application has a global scope and constants in the global scope are not bad but the only correct way if the constant is globally valid. note, each enum defined outside of a class scope defines constants in global scope.

4. since the compiler replace the symbol with the value, this can lead to nasty surprises

can you elaborate? as explained any of the constants was replaced by the compiler. this makes a type-check and prevents from spoiling or corrupting constants at runtime.

note, i also prefer enum constants over macros in c++ (and even in c) and there are a few good reasons to do so. but using simple macro constants is neither bad practice nor error prone, but simply not avoidable as they were used widely in every library where you have no alternative.  

Sara
4. since the compiler replace the symbol with the value, this can lead to nasty surprises

can you elaborate? as explained any of the constants was replaced by the compiler. this makes a type-check and prevents from spoiling or corrupting constants at runtime.
Consider the following code:
#define MAX 3

int main()
{
        const int MAX = 40;
        return 0;
}

Open in new window

This will produce the following compile error:
expected unqualified-id before numeric constant

The error is due to the preprocessor macro in conflict with the local constant defined in the main function, and the error message don't help much.
On very small projects (only one source file), it is very easy to fix as you have all the source code under your eyes.
On small multi-files projects, it is already head-breaking as you'll need to search in all source files.
On bigger projects, it is just a nightmare and unacceptable du to the quantity of source files.

So the best solution is to define constants, and unless there is a valid reason to give it global scope, define it locally.