我的列表有问题(奇怪的 Malloc 错误继续)

Problems with my list (Weird Malloc Error Continued)

我决定详细说明我的问题,因为我能够嗅出一些具体情况。显然,它与列表有关,但我不太确定如何修复它。更具体地说,我正在寻找一种方法来尝试重写列表的某个部分,但它给了我一个错误,如果你读过我之前的 post.

,你就会知道这个错误

这是我的列表处理代码:

typedef struct list_t
{
    pid_t pid;
    int jid;
    char *runstat;
    char *cmdline;
    struct list_t *next;
} list_t;

list_t *jobs_list = NULL;

void add_element(list_t **list, pid_t pid, int jid, char *runstat, char *cmdline)
{
    list_t *e;

    if (*list == NULL)  // New empty list.
    {
        *list = (list_t *) malloc(sizeof(list_t));
        (*list)->pid = pid;
        (*list)->jid = jid;
        (*list)->runstat = strndup(runstat, MAXCHARS);
        (*list)->cmdline = strndup(cmdline, MAXCHARS);
        (*list)->next = NULL;
    }
    else  // List with at least one element.
    {
        // Loop through elements, so that e is left
        // pointing to the last one in the list.
        for (e = *list; e->next != NULL; e = e->next)
            ; // (Do nothing.)

        e->next = (list_t *) malloc(sizeof(list_t));
        e = e->next;
        e->pid = pid;
        e->jid = jid;
        e->runstat = strndup(runstat, MAXCHARS);
        e->cmdline = strndup(cmdline, MAXCHARS);
        e->next = NULL;
    }
}

void fg_list_handler(list_t ** list, pid_t pid, int jid) {

}

void change_running_status(list_t **list, pid_t pid, char *runstat) {
  //THe code I wrote with changing statuses in the list for programs.

  list_t *e;

  e = *list;

  if (e->next == NULL) {
    strncpy(e->runstat, runstat, MAXCHARS);
  } else {
    for (e; e != NULL; e->next) {
      if (pid == e->pid) {
        strncpy(e->runstat, runstat, MAXCHARS);
        break;
        }
  
    }
  }

 

}

您是否知道如何修复它,以便我可以更改列表的特定值而不会出现无法理解的堆损坏错误?

简单易行...;-)

add_element 中,不要 使用 strndup——这对您的情况没有帮助(请改用 strdup)。

保证结果的长度是MAXCHARS

change_running_status 中,如果 runstat 参数的长度大于 strdup 创建的长度(nee strndup) 在 add_element.


例如...

如果你这样做:

add_element(&mylist,pid,jid,"foo","bar");

但是,那么,以后再做:

change_running_status(&mylist,"hello world");

这将溢出为 e->runstat 分配的 space 并破坏堆。


请注意,在 for 循环中,迭代子句是:e->next。这 没有 效果。你想要:e = e->next.

这是更正后的代码:

void
change(list_t *e,const char *runstat)
{
    char *str;

    // safety -- dup the string first to prevent [possible] use after free
    str = strdup(runstat);

    // free the old string
    free(e->runstat);

    // add in the new string
    e->runstat = str;
}

void
change_running_status(list_t **list,pid_t pid,char *runstat)
{
    // THe code I wrote with changing statuses in the list for programs.

    list_t *e;

    e = *list;

    if (e->next == NULL)
        change(e,runstat);
    else {
        for (;  e != NULL;  e = e->next) {
            if (pid == e->pid) {
                change(e,runstat);
                break;
            }
        }
    }
}