全局结构内存错误

Posted

技术标签:

【中文标题】全局结构内存错误【英文标题】:Global struct memory error 【发布时间】:2015-07-16 15:35:38 【问题描述】:

我的程序使用libconfig 读取配置文件并将值保存到全局结构。它工作正常,但 valgrind 说有错误。并且该错误仅显示 char 指针变量。那是什么错误以及如何解决?谢谢

#include <stdio.h>
#include <libconfig.h>
#include "stdlib.h"
#define conf_file "myconf"

struct setting_data

    int number;
    const char* timeformat;
;
struct setting_data conf_data;
void read_config();
int main()
    read_config();
    printf("%d @ %p\n", conf_data.number,&conf_data.number);
    printf("%s @ %p\n", conf_data.timeformat,&conf_data.timeformat);



void read_config()
    config_t cfg;
    // config_setting_t *rules, *settings,*m_number,*device,*sendduration,*pin_code;
    config_init(&cfg);

    if(! config_read_file(&cfg, conf_file))
    
        fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
                config_error_line(&cfg), config_error_text(&cfg));
        config_destroy(&cfg);
        exit(1);
    
    // conf_data.number        = config_setting_get_int   (config_lookup(&cfg, "number"       ));
    config_lookup_int(&cfg,"number",&conf_data.number);
    config_lookup_string(&cfg, "timeformat", &conf_data.timeformat);
    config_destroy(&cfg);

==8238== 大小为 1 的读取无效

==8238== 在 0x50AFBC9:_IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1317)

==8238== by 0x5083972: vfprintf (vfprintf.c:1629)

==8238== by 0x508C269: printf (printf.c:35)

==8238== by 0x400993: main (test.c:16)

....

==8238== 地址 0x53cdb0c 是一个大小为 15 的块内的 12 个字节已释放

==8238== 错误摘要:来自 5 个上下文的 43 个错误(已抑制:4 个来自 4 个)

【问题讨论】:

【参考方案1】:

来自the libconfig api manual

config_lookup_string() 返回的字符串的存储由库管理,并在设置被销毁或设置值更改时自动释放;调用者不得释放该字符串。

所以如果你想在config_destroy()之后使用config_lookup_string()返回的指针,你需要将它复制到另一个数组中

【讨论】:

【参考方案2】:

libconfig 正在向您传递一个指向其内部字符串存储的指针,以存储 timeformat 值。然后,当您执行 config_destroy() 导致全局结构的时间格式指针无效时,它会被释放。为了避免这种strdup() libconfig 返回给您的时间格式字符串:

const char *time_str;
config_lookup_string(&cfg, "timeformat", &time_str);
conf_data.timeformat = strdup(time_str);
config_destroy(&cfg);
/* conf_data.timeformat is still valid */

【讨论】:

感谢您的回答。看起来我必须在使用后释放那个 conf_data.timeformat 。除了 strdup 还有其他选择吗? @akiD 是的,从技术上讲,您必须在使用后释放 conf_data.timeformat 以避免内存泄漏,但是如果这是在程序的整个生命周期中都存在的全局配置数据,则忽略 free()它在程序退出时并不是什么大问题IMO。还有其他方法可以复制字符串(memcpy 等),但 strdup() 是最直接的。

以上是关于全局结构内存错误的主要内容,如果未能解决你的问题,请参考以下文章

全局指针导致分段错误?

为结构“错误”分配内存

C:更新共享内存 pthread 并使用 strncpy

GDB调试工具动态加载内存管理(day04)

在字符串和结构数组中查找动态内存分配错误

无法在类的结构中达到内存错误