【问题标题】:Valgrind: "Conditional jump or move depends on uninitialised value(s)"Valgrind:“有条件的跳转或移动取决于未初始化的值”
【发布时间】:2014-04-07 20:57:01
【问题描述】:

我正在尝试编写一个将新结构添加到链表中的函数。无论我做什么,Valgrind 都会不断给我这个错误。代码如下:

/* Stores a new address record to the linked list
 * 
 * Parameters:
 * first: pointer to the start of the linked list
 * name: name of the new record to be added (same name can be stored multiple times)
 * ad: IPv4 address to be stored with the name
 * 
 * Returns:
 * Pointer to the new node in linked list (that becomes the first node in list) */
struct addrRecord *storeIPv4(struct addrRecord *first, const char *name, const addr_4 *ad)
{
    if (first==NULL) {
        first=malloc(sizeof(struct addrRecord));
        if (!first)
             return NULL;
        strcpy(first->name,name);
        first->type=IPv4;
        strcpy(first->u.in4.a,ad);
        first->next=NULL;
        return first;
    }
    struct addrRecord *new=malloc(sizeof(struct addrRecord));
    if (!new)
        return NULL;
    strcpy(new->name,name);
    new->type=IPv4;
    strcpy(new->u.in4.a,ad);
    new->next=first;
    return new;
}

这里是主要代码:

struct addrRecord *recs = NULL;
addr_4 ad4 = {{128, 214, 4, 64}};
recs = storeIPv4(recs, "www.example.com", &ad4);
if (!recs)
    return EXIT_FAILURE;

最后是标题:

#ifndef AALTO_ADDRESS_H
#define AALTO_ADDRESS_H

/* container for 32-bit IPv4 address */
typedef struct {
    char a[4];
} addr_4;

/* container for 128-bit IPv6 address */
typedef struct {
    char a[16];
} addr_6;

/* container for Unix domain address */
typedef struct {
    char a[108];
} addr_un;

typedef enum {
    NONE, // address not in use
    IPv4,
    IPv6,
    UNIX
} adType;

/* One node in linked list of name / address entries */
struct addrRecord {
    char name[20];
    adType type;
    union {
        addr_4 in4;
        addr_6 in6;
        addr_un un;
    } u;
        struct addrRecord *next;
};

/* Store IPv4 address to addrRecord */
struct addrRecord *storeIPv4(struct addrRecord *first, const char *name, const addr_4 *ad);

/* Store IPv6 address to addrRecord */
struct addrRecord *storeIPv6(struct addrRecord *first, const char *name, const addr_6 *ad);

/* Store Unix domain address to addrRecord */
struct addrRecord *storeUnix(struct addrRecord *first, const char *name, const addr_un *ad);

/* Find address from linked list starting from 'first' */
struct addrRecord *findAddress(struct addrRecord *first, const char *name);

/* Prints the address in address record to standard output */
void printAddress(struct addrRecord *ad);

#endif  /* AALTO_ADDRESS_H */

我得到的错误:

==358== Conditional jump or move depends on uninitialised value(s)
==358==    at 0x4C25897: strcpy (mc_replace_strmem.c:311)
==358==    by 0x403203: storeIPv4 (address.c:79)
==358==    by 0x401706: initRec (test_source.c:30)
==358==    by 0x401AB0: test_store (test_source.c:97)
==358==    by 0x406350: srunner_run_all (in /tmc/test/test)
==358==    by 0x402C5A: tmc_run_tests (tmc-check.c:121)
==358==    by 0x402915: main (test_source.c:324)

抱歉,代码冗长,提前致谢。

【问题讨论】:

    标签: c pointers memory valgrind strcpy


    【解决方案1】:

    这只是一个猜测,因为您的代码不是一个完整的示例。

    尽量不要使用 strcpy 复制 addr_4 结构。而是使用 memcpy。

    所以,改变这一行:

    strcpy(first->u.in4.a,ad);
    

    到这里:

    memcpy(first->u.in4.a,ad,sizeof(*ad));
    

    strcpy 需要一个以 null 结尾的字符串,而广告可能不是这样。

    【讨论】:

    • 成功了,非常感谢!介意解释为什么 ad 不是以空字符结尾的字符串吗?我的意思是 addr_4 结构由一个 char[4] 数组组成,这不是自动包含空字符吗?另外,这有点离题,但是 addr_4 ad4 = {{128, 214, 4, 64}} 中的双花括号是什么意思; ?
    • 当然它不是以 null 结尾的,因为它不是一个字符串,而是一个用于存储 Internet 地址的 4 字节数组。无论如何都要投一票。
    • @user3384360 addr_4 ad4 = {{128, 214, 4, 64}}; 用这 4 个值初始化结构 ad4 中的字段。
    猜你喜欢
    • 2011-04-18
    • 2016-07-24
    • 2014-11-30
    • 2016-09-03
    • 1970-01-01
    • 2019-08-14
    相关资源
    最近更新 更多