2

function call in data structure

I want to delete the i-th element in the sequence table, and delete it by calling my own defined DelList function in the main function, but after compiling, I can't print out the value of the deleted element as expected. The code before line 48 works fine, but it seems that the DelList function cannot be called, resulting in no deleted elements being printed. Is there a problem with calling the DelList function? Or is there a problem with the return of the DelList function? Thank you

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

#define MAXSIZE 100  
#define OK 1
#define ERROR 0

typedef int ElemType;  /*Assume that the data elements in the sequence table 
                        are integers*/
typedef struct {
    ElemType elem[MAXSIZE];
    int last;
}SeqList;

int  DelList(SeqList *L, int i, ElemType *e)
/*The i-th data element is deleted in the sequence table L, and its value is returned with the pointer parameter e. The legal value of i is 1 ≤ i ≤ L. last +1 */
{
    int k;
    if ((i < 1) || (i > L->last + 1))
    {
        printf("Deleting the location is not legal!");
        return(ERROR);
    }
    *e = L->elem[i - 1];  /* Store the deleted element in the variable pointed to by e*/
    for (k = i; i <= L->last; k++)
        L->elem[k - 1] = L->elem[k];  /*Move the following elements forward*/
    L->last--;
    return(OK);
}

void main()
{
    SeqList *l;
    int p, r;
    int *q;
    int i;
    l = (SeqList*)malloc(sizeof(SeqList));
    q = (int*)malloc(sizeof(int));
    printf("Please enter the length :");
    scanf("%d", &r);
    l->last = r - 1;
    printf("Please enter the value of each element:\n");
    for (i = 0; i <= l->last; i++)
    {
        scanf("%d", &l->elem[i]);
    }
    printf("Please enter the location of the element you want to delete:\n");
    scanf("%d", &p);
    DelList(l, p, q);
    printf("The deleted element value is:%d\n", *q);
}

Compile can pass but not the result I want

KPCT
  • 3,815
  • 2
  • 16
  • 34
  • This is PURE C!!! I will remove C++ tag so you do not get burned – KPCT Jun 22 '19 at 02:36
  • Are you running this on Windows? I compile our code on OpenSUSE just fine, but when I run it on Windows I'm noticing that Windows Defender is blocking program execution. – jhelphenstine Jun 22 '19 at 03:58
  • So there's interesting behavior -- when I give it the max value for the location to delete, the code functions. DelList is getting called -- I'm using printf debugging to prove that -- but your for (k = i; i <= L->last; k++) isn't working for values smaller than the max. – jhelphenstine Jun 22 '19 at 04:06
  • @jhelphenstine you can check my answer for an explanation. – ggorlen Jun 22 '19 at 04:09

1 Answers1

3

There is a small typo causing grief:

for (k = i; i <= L->last; k++) {
//          ^

Here, the k index is being incremented, but not being tested against the end of the array. After writing past the end of the array, the behavior is undefined.

Change this line to:

for (k = i; k <= L->last; k++) {
//          ^

Additional remarks:

  • I recommend using SeqList.length instead of SeqList.last. Iterating from i <= last is much less natural than i < length. One-indexing adds to the cognitive load--you can decrement user input to normalize it before sending it into your function, which can then operate on a zero-indexed array.
  • Consider using dynamic memory to avoid the fixed size of the array, especially if you're taking the data from I/O. At minimum, add a bounds check to avoid overflowing the buffer.
  • Consider using a doubly linked list if you're planning on performing frequent deletions in the middle of the list. Array deletions other than the furthest-right element are O(n), while a doubly linked list can do it in O(1). The drawback is no random access and some overhead associated with creating nodes.
  • Use descriptive variable names. l, p, r, q are only going to frustrate debugging efforts.
  • Use #include <stdbool.h> instead of #DEFINE OK 1.
  • Unless you're on an old compiler, variables need not be declared at the top of scopes.
  • No need to cast the result of malloc() (although I realize this question started out tagged C++).
  • Always free allocated memory. You can declare l and q on the stack and use the & reference operator to pass the address into functions.
  • Use int main() and return 0; from it to notify the shell that your program successfully terminated.

Here's a possible re-write that addresses some of these points:

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

typedef struct {
    int *data;
    int length;
} SeqList;

bool list_delete(SeqList *list, int idx_to_remove, int *removed_element) {
    if (idx_to_remove < 0 || idx_to_remove >= list->length) {
        return false;
    }

    *removed_element = list->data[idx_to_remove];
    list->length--;

    for (int i = idx_to_remove; i < list->length; i++) {
        list->data[i] = list->data[i+1];
    }

    return true;
}

int main() {
    SeqList list;
    int deleted_element;
    int idx_to_delete;

    printf("Please enter the length: ");
    scanf("%d", &list.length);
    list.data = malloc(sizeof(int) * list.length);

    for (int i = 0; i < list.length; i++) {
        printf("Enter the value for element %d: ", 1 + i);
        scanf("%d", &list.data[i]);
    }

    do {
        printf("Please enter the index of the element you want to delete: ");
        scanf("%d", &idx_to_delete);
    } while (!list_delete(&list, idx_to_delete - 1, &deleted_element));

    printf("The deleted element value is: %d\n", deleted_element);
    puts("The elements left in the list are:");

    for (int i = 0; i < list.length; i++) {
        printf("%d ", list.data[i]);
    }

    puts("");
    free(list.data);
    return 0;
}

Sample run:

Please enter the length: 4
Enter the value for element 1: 11
Enter the value for element 2: 22
Enter the value for element 3: 33
Enter the value for element 4: 44
Please enter the index of the element you want to delete: 6
Please enter the index of the element you want to delete: -1
Please enter the index of the element you want to delete: 5
Please enter the index of the element you want to delete: 4
The deleted element value is: 44
The elements left in the list are:
11 22 33
ggorlen
  • 26,337
  • 5
  • 34
  • 50