【发布时间】:2018-01-13 21:06:21
【问题描述】:
我正在使用 Valgrind 对小型应用程序的 C 代码进行内存分析,它使用 DFS 方法找出图中的所有路径。但是我仍然遇到一些错误,主要是在这部分代码中:
int process_edges(VoidStack *edges, char *buffer)
{
char weight[DATE_LENGTH] = "";
char min_weight[DATE_LENGTH] = "", max_weight[DATE_LENGTH] = "";
int metric;
VoidStack *reverse = malloc(sizeof(VoidStack));
void_stack_new(reverse, DATE_LENGTH);
/* Create reverse stack to have edges in correct order */
while (edges->loglength != 0)
{
void_stack_pop(edges, weight);
void_stack_push(reverse, weight);
}
if (reverse->loglength >= 1)
{
void_stack_pop(reverse, weight);
strcpy(max_weight, weight);
strcpy(min_weight, weight);
sprintf(buffer + strlen(buffer), "%s", weight);
void_stack_push(edges, weight);
}
我得到了这些 valgrind 错误:
==1399== Conditional jump or move depends on uninitialised value(s)
==1399== at 0x4C2C2AB: strcpy (vg_replace_strmem.c:458)
==1399== by 0x4010D5: process_edges (in /home/adam/C/dfs.out)
==1399== by 0x401508: dfs (in /home/adam/C/dfs.out)
==1399== by 0x4015A9: dfs (in /home/adam/C/dfs.out)
==1399== by 0x40172A: all_paths (in /home/adam/C/dfs.out)
==1399== by 0x401AEC: main (in /home/adam/C/dfs.out)
==1399== Uninitialised value was created by a stack allocation
==1399== at 0x40100D: process_edges (in /home/adam/C/dfs.out)
==1399==
==1399== Conditional jump or move depends on uninitialised value(s)
==1399== at 0x4C2C2AB: strcpy (vg_replace_strmem.c:458)
==1399== by 0x4010E8: process_edges (in /home/adam/C/dfs.out)
==1399== by 0x401508: dfs (in /home/adam/C/dfs.out)
==1399== by 0x4015A9: dfs (in /home/adam/C/dfs.out)
==1399== by 0x40172A: all_paths (in /home/adam/C/dfs.out)
==1399== by 0x401AEC: main (in /home/adam/C/dfs.out)
==1399== Uninitialised value was created by a stack allocation
==1399== at 0x40100D: process_edges (in /home/adam/C/dfs.out)
我不知道如何修复这些错误。
我正在使用这些参数运行 Valgrind
--leak-check=full --track-origins=yes --show-reachable=yes
完整代码可在https://github.com/AdamPalaxo/KIV-PC获取。
编辑:
为void_stack_new、void_stack_push 和void_stack_pop 函数添加了代码。
/* Creates new stack with given element size, allocates memory */
void void_stack_new(VoidStack *s, int element_size)
{
s->element_size = element_size;
s->loglength = 0;
s->allocated_length = 4;
s->elements = malloc((size_t) 4 * element_size);
}
/* Grows stack in case when maximal length of stack would be exceeded */
static void stack_grow(VoidStack *s)
{
s->allocated_length *= 2;
s->elements = realloc(s->elements, (size_t) s->allocated_length * s->element_size);
}
/* Pushes new element to stack on given address */
void void_stack_push(VoidStack *s, void *element_address)
{
void *target;
if(s->loglength == s->allocated_length)
{
stack_grow(s);
}
target = (char *)s->elements + s->loglength * s->element_size;
memcpy(target, element_address, (size_t) s->element_size);
s->loglength++;
}
/* Pops element from top of stack to given address */
void void_stack_pop(VoidStack *s, void *element_address)
{
void *source;
s->loglength--;
source = (char *) s->elements + (s->loglength) * s->element_size;
memcpy(element_address, source, (size_t) s->element_size);
}
【问题讨论】:
-
您确定
void_stack_push和void_stack_pop没有超出限制吗? minimal verifiable example 在这里会有所帮助。 -
@Pablo 我为这些函数添加了代码,但我认为(并希望)它们不会超出限制
-
你应该检查错误,检查
realloc返回NULL,你的堆栈不是空的/满的。除此之外,功能看起来还可以。但是,我仍然不能保证它们正确运行,因为我不知道您是如何初始化堆栈的。例如,s->element_size持有什么值?如果是字符串(例如weight),您是否考虑使用\0终止字节?真的所有字符串的长度都相同(您的堆栈希望输入始终具有相同的大小)吗?你如何初始化你的堆栈? -
好点,谢谢。我还添加了函数
void_stack_new,用于初始化堆栈。值s->element_size包含 11,因为输入数据的格式为 YYYY-MM-DD 加上我正在考虑\0终止字节。所以堆栈总是期望输入总是相同的大小。 -
我不太喜欢你的
void_stack_new功能。allocated_length是什么,您的堆栈开始的元素数?如果是这样,malloc应该如下所示:malloc(s->allocated_length * element_size)。
标签: c memory-management valgrind