C language sequence table implementation code troubleshooting

  • 2020-04-02 01:57:49
  • OfStack

Today, I was going to write a piece of code to practice my hands, but I had a good idea. I finally stumbled on this mistake and it took me 4 hours to solve it.



#ifndef __SQLIST_H__
#define __DWLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE     50
#define OK          0
#define ERR         -1
typedef int elemtype;
typedef struct {
    elemtype data[MAXSIZE];
    int      len;
}sqlist;
int init_list(sqlist *L);
int destroy_list(sqlist *L);
int list_empty(sqlist L);
int list_length(sqlist L);
int disp_list(sqlist L);
int get_elem(sqlist L, int i, elemtype *e);
int local_elem(sqlist L, elemtype e);
int list_insert(sqlist *L, int i, elemtype e);
int list_delete(sqlist *L, int i, elemtype *e);
#endif


#include "sqlist.h"
#if 0
#define ERR_NONE_ERROR        0
#define ERR_FUNC_EXEC         1
#define ERR_FILE_OPEN         2
char *error_msg[] = {
        " Successful execution , No error ",
        " Function execution error ",
        " File opening error ",
};
int my_errno = 0;
#endif
int main(void)
{
    int ret = 0;
    int i = 0;
    sqlist slist;
    elemtype e;
    memset(&slist, 0, sizeof(slist));
    printf("length:%dn", slist.len);
    ret = init_list(&slist);
    if (OK != ret)
        return -1;
    ret = list_empty(slist);
    printf(" The length of the :%dn", slist.len);
    if (OK == ret)
        printf(" The order table is empty n");
    if (ERR == ret)
        printf(" The order table is not empty n");
    for (i = 0; i < 10; i++) {
        e = (elemtype)i;
        list_insert(&slist, i, e);
    }
    printf(" Insert data n");
    ret = list_empty(slist);
    if (OK == ret)
        printf(" The order table is empty n");
    if (ERR == ret)
        printf(" The order table is not empty n");
    printf("after length%dn", list_length(slist));
    disp_list(slist);
    destroy_list(&slist);
    return 0;
}

int init_list(sqlist *L)
{
    L = (sqlist *)malloc(sizeof(sqlist));
    if (NULL == L) {
        L = NULL;
        return -1;
    }
    L->len = 0;
    return 0;
}

int destroy_list(sqlist *L)
{
    free(L);
    return 0;
}

int list_empty(sqlist L)
{
    if (0 == L.len)
        return 0;
    return -1;
}

int list_length(sqlist L)
{
    return L.len;
}

int disp_list(sqlist L)
{
    int i = 0;
    if (0 >= L.len)
        return -1;
    for (i = 0; i < L.len; i++)
        printf("%dt", L.data[i]);
    
    printf("n");
    return 0;
}

int get_elem(sqlist L, int i, elemtype *e)
{
    if (i < 0 || i >= L.len) {
        e = NULL;
        return -1;
    }
    *e = L.data[i];
    
    return 0;
}

int local_elem(sqlist L, elemtype e)
{
    int i = 0;
    for (i = 0; i < L.len; i++) {
        if (e == L.data[i])
            return i;
    }
    return -1;
}

int list_insert(sqlist *L, int i, elemtype e)
{
    int j = 0;
    if (i < 0 || i > MAXSIZE-1)
        return -1;
    for (j = L->len; j > i; j--)
        L->data[j] = L->data[j-1];
    L->data[i] = e;
    L->len++;
    return 0;
}

int list_delete(sqlist *L, int i, elemtype *e)
{
    int j = 0;
    if (i < 0 || i >=L->len)
        return -1;
    *e = L->data[i];
    for (j = i; j < (L->len-1); j++)
        L->data[j] = L->data[j+1];
    L->len--;
    return 0;
}

I'm very proud of myself, I think it's written very well, let's run it and see,

< img SRC = "border = 0 / / files.jb51.net/file_images/article/201312/20131208111859.png? 2013118111958 ">

The results were totally unexpected.

All right! Now analyze the error!

Look at the definition in main


int ret = 0;
   int i = 0;
   sqlist slist;
   elemtype e;


Look at the initialization function init_list


int init_list(sqlist *L)
{
   L = (sqlist *)malloc(sizeof(sqlist));
    if (NULL == L) {
        L = NULL;
        return -1;
    }
    L->len = 0;
    return 0;
}

As the smart ones can see, the slist space I defined in main is on the stack, and I've just allocated this thing to heap space all at once in init_list, and the slist is not a pointer, so it doesn't point at all, so of course it's very wrong.

For example, a stack and a heap are two parallel worlds, and only a pointer is a wormhole that traverses the two worlds.

Knowing the cause is easy to solve.

Since the stack will automatically allocate space, there is no need to apply for space again. Therefore, init_list is changed to:


int init_list(sqlist *L)
{
    /*
    L = (sqlist *)malloc(sizeof(sqlist));
    if (NULL == L) {
        L = NULL;
        return -1;
    }
    */
    L->len = 0;
    return 0;
}

It is ok

The lesson is clear.


Related articles: