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