【问题标题】:C, Invalid write with valgrind and void* variableC,使用 valgrind 和 void* 变量写入无效
【发布时间】:2018-10-20 08:24:39
【问题描述】:

我想将变量 void* 分配给结构中的属性 void*。 我的结构:

struct data{
    int n;
    void * cl;
}typedef data;

那么,我就有了这个功能:

void f(void *cl, int n){
    struct data *data = malloc(sizeof(data));
    data->cl = cl; //"Invalid write of size 8" from valgrind
    data->n = n;
}

编辑:“void *cl”为空,我不知道为什么(但不是数据) 我这样称呼它:

f(args_f(2), 1);

关于args_f:

struct st_args * args_f(int n)
    {
        struct st_args *args = malloc(sizeof(struct st_args));
        if (args == NULL)
            return NULL;

        args->n = n;
        return args;
    }

结构体 st_args:

struct st_args{
    int n;
    }typedef st_args;

在我的函数 f 中,当我尝试赋值“data->cl = cl;”时,valgrind 在这一行上显示“大小为 8 的无效写入”。这是为什么呢?

【问题讨论】:

  • 不完全是一个解决方案,但您应该检查datamalloc 之后是否为NULL
  • 我发现f "void * cl" 的参数是null,但不是data
  • malloc(sizeof(data)); 返回指针的大小(4/8 字节 - 取决于系统),你得到了声明的 data 指针的大小。你应该写malloc(sizeof(struct data))来为数据对象分配内存。
  • 请不要撒谎。您提供的代码无法编译,因此您不可能运行它。请提供一个最小的、可运行的问题演示。 (见minimal reproducible example。)
  • 或者写struct data *data = malloc(sizeof *data);,你也应该检查data != NULL来验证分配,就像你为args做的那样。

标签: c segmentation-fault valgrind


【解决方案1】:

我在这里看到了一个问题:struct st_args *args 是本地的,而你有 returned 它,但没有分配适当的内存。

struct data *data = malloc(sizeof(data));

在这种情况下,data 是一个指针,malloc 将分配 4(或 8)字节的内存。应该是,

struct data *data = malloc(sizeof(struct data));

这将分配(如果可用)所需的内存并且段错误将消失。

此外,您应该检查datamalloc 之后是否为NULL,如果是,则按照您在args_f 函数中所做的方式处理错误。

这正是我们应该避免用户定义的数据类型和变量名称可以相同的变量命名约定的确切原因。 就此而言,当我有 typedef 时,我通常会在其后面加上 _t 后缀以避免任何混淆。

例如,

这个

struct data{
    int n;
    void * cl;
}typedef data;

在我的代码中会是这样的

typedef struct stData {
    int32_t i_N;
    void *p_cl;
} data_t;

【讨论】:

    猜你喜欢
    • 2014-08-04
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    相关资源
    最近更新 更多