为什么用 Valgrind 执行 C 程序时 bug 消失了?
我在命令函数开始时分配了两个相当大的结构:第一个是数组和单个值的简单结构,第二个有其内部子结构。
之后,我用一些 fill_functions(struct_1) 填充第一个结构,然后使用第一个结构和外部文件中的数据用其他结构填充 struct_2。 从 struct_1 填充的内容 - 可以被视为键数据和键数据的“渲染”。 从文件中填充的是价值数据,即作为结果要收集的目标信息;所有值数据均由键数据字段提取。
最后,我输出 struct_2 中的所有值。
我的代码方案是这样的:
typedef struct struct_1
{
// a lot of arrays, ints, chars..
}
STRUCT_1;
typedef struct sub_struct_A
{
char strings[5][100];
// arrays, ints, chars..
}
SUB_A;
typedef struct sub_struct_B
{
char strings[5][10][10];
// arrays, ints, chars..
}
SUB_B;
typedef struct struct_2
{
SUB_A sub_struct_A[10];
SUB_B sub_struct_B[100];
}
STRUCT_2;
main()
{
// take it as somewhere before a config struct was initialized..
char input[100]={0};
// no matter whats inside..
some_input(input, config);
STRUCT_1 *s1 = NULL;
s1 = (s1 *)malloc(sizeof(STRUCT_1));
STRUCT_2 *s2 = NULL;
s2 = (s2 *)malloc(sizeof(STRUCT_2));
fill_struct_1(input, s1, config);
fill_struct_2(s1, s2, config);
output_struct_2(s2, config);
free(s1); free(s2);
}
void fill_struct_2(STRUCT_1 *s1, STRUCT_2 *s2, CONF_STRUCT config)
{
fill_keys_data(s1, s2);
fill_value_data(s1, s2, config);
}
void fill_value_data(STRUCT_1 *s1, STRUCT_2 *s2, CONF_STRUCT config)
{
get__tokenized_buffer__from_file();
extract_values__from_buf_and_s1__by_conf(s1, s2, config);
}
问题是: 当我在 sub-struct_B[0].strings[0][1]
上按顺序输出两个子结构数组中的所有条目时 - 我从 获取数据>sub-struct_A[0].strings[0]
。 对于 sub-struct_B[0].some_int_val_X
- 我得到值 (757935400)
,该字段不允许该值,可能的最大值约为 (150)
。
所有其他输出始终正常。 'sub-struct_B[i]'
中的每个(i)
都被填充并输出OK。
当我使用 Valgrind 检查问题的踪迹时,问题就消失了。 是的,Valgrind 表示可能丢失:8 个块中的 8,904 字节
。
但我对这个工具还很陌生,所以这些信息对我来说什么也没有。现在我不知道如何修复这些可能的泄漏;我的代码 - 工作,不是绝对,但很好。也许我的问题出在这个 Valgrind 消息上,我不知道。
每个子结构的填充逻辑都很庞大,带有rand()
和内部过滤器和提取器。抱歉,我无法给出这种逻辑的抽象方案。
现在我猜测,也许一些远方指针出了问题。但我无法想象从哪里开始我的搜索。 sub-struct_B
中的所有 99 个条目均正确输出,但只有 [0]-entry 给出了错误的输出。
很少情况下,[0]-entry 甚至给我的不是来自 sub_struct_A
的数据,而是来自其他地方的大量垃圾。
我唯一的猜测是我在某个地方做了错误的指针算术。不是那么大的想法..
任何人都可以给我一些开始的提示吗?
我知道我是一对一地解决我的问题,只是向在 C 指针调试方面特别有经验的人寻求好的建议。
如果这个猜谜游戏不是你们想要的,那么请给我一个简单问题的答案:
怎么可能,Valgrind 是 100% 正确的输出,并且没有 - 损坏? Valgrind 如何在不修复代码的情况下修复程序?
exec 之间的唯一区别是,对于 Valgrind,我使用标志“-g”进行编译,但对于常见用途 - 使用“-o”。
谢谢。
I'm malloc-ing two pretty big structures at the command-function start: first is a plain structure of arrays and single values, second have its inner sub-structures.
After that, I'm filling first structure with some filling_functions(struct_1), and then I fill struct_2 with other, using data from first struct and from external files.
What is filled from struct_1 - can be minded as keys-data and "render" of key-data.
What is filled from files - is value-data, target information to collect as a result; all value-data are extracted by keys-data fields.
Finally, I'm outputting all values from struct_2.
Scheme of my code some kind of that:
typedef struct struct_1
{
// a lot of arrays, ints, chars..
}
STRUCT_1;
typedef struct sub_struct_A
{
char strings[5][100];
// arrays, ints, chars..
}
SUB_A;
typedef struct sub_struct_B
{
char strings[5][10][10];
// arrays, ints, chars..
}
SUB_B;
typedef struct struct_2
{
SUB_A sub_struct_A[10];
SUB_B sub_struct_B[100];
}
STRUCT_2;
main()
{
// take it as somewhere before a config struct was initialized..
char input[100]={0};
// no matter whats inside..
some_input(input, config);
STRUCT_1 *s1 = NULL;
s1 = (s1 *)malloc(sizeof(STRUCT_1));
STRUCT_2 *s2 = NULL;
s2 = (s2 *)malloc(sizeof(STRUCT_2));
fill_struct_1(input, s1, config);
fill_struct_2(s1, s2, config);
output_struct_2(s2, config);
free(s1); free(s2);
}
void fill_struct_2(STRUCT_1 *s1, STRUCT_2 *s2, CONF_STRUCT config)
{
fill_keys_data(s1, s2);
fill_value_data(s1, s2, config);
}
void fill_value_data(STRUCT_1 *s1, STRUCT_2 *s2, CONF_STRUCT config)
{
get__tokenized_buffer__from_file();
extract_values__from_buf_and_s1__by_conf(s1, s2, config);
}
The problem is:
When I'm outputting sequentially all entries from arrays of both sub-structs, on the sub-struct_B[0].strings[0][1]
-- I get the piece of data from sub-struct_A[0].strings[0]
.
And for sub-struct_B[0].some_int_val_X
-- I get value (757935400)
, which is not allowed for that field, possible maximum for which is about (150)
.
All other output is always OK. Each (i)
in 'sub-struct_B[i]'
is filled and outputted OK.
When I'm using Valgrind to check, what's the trace of my problem, the problem just disappears..
And yes, Valgrind says that there's possibly lost: 8,904 bytes in 8 blocks
.
But I'm very new to this tool, so that information gives me just nothing. Now I don't know how to fix these possible leaks; my code - works, not absolutely, but fine. Maybe my problem lies upon this Valgrind message, i don't know.
Filling logic of each sub-struct is huge, with rand()
's and inner filtrations and extractors. I can't give an abstract scheme of this logic, sorry.
Now I'm guessing, maybe something goes wrong with some distant side pointers. But I can't imagine where to start my search. All 99 entries from sub-struct_B
are outputted correctly, but only [0]-entry gives me bad output.
Rarely, [0]-entry even gives me not that data from sub_struct_A
, but a lot of garbage from other places.
My only guess is that I am doing wrong pointer arithmetics somewhere. Not so big idea..
Can anybody give me some hints to start?
I know that I'm one-on-one with my problem, just seeking for good suggestions from people being experienced specially in C-pointers debugging.
If this guess-game is not what you guys seeking on, than give me an answer on one simple question, please:
How can that be, that with Valgrind -- there is 100% correct output, and without - corrupted? How Valgrind can fix the program without fixing the code??
Only difference between execs, is that for Valgrind I am compiling with flag '-g', but for common use - with '-o'.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论