struct中的字符串。损坏

时间:2012-06-23 22:26:23

标签: c struct

有这样的结构。

struct Address {
    int id;
    int set;
    char name[MAX_DATA];
    char email[MAX_DATA];
};

设定地址的功能。

void Database_set(struct Connection *conn, int id, const char *name, const char *email) {
    struct Address *addr = &conn->db->rows[id];
    if(addr->set) die("Address already set");

    addr->set = 1;
    char *res = strncpy(addr->name, name, MAX_DATA);
    if(!res) die("Name copy failed");

    *res = strncpy(addr->email, email, MAX_DATA);
    if(!res) die("Email copy failed");
}

但addr-> name的第一个字符在此行之后被破坏。

*res = strncpy(addr->email, email, MAX_DATA);

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

strncpy

之后返回其第一个参数
char *res = strncpy(addr->name, name, MAX_DATA);

变量res包含addr->name(相当于&(addr->name[0]))所以

*res = strncpy(addr->email, email, MAX_DATA);

运行它相当于

addr->name[0] = strncpy(addr->email, email, MAX_DATA);

这项任务破坏了addr->name的第一个字符。正如Greg Hewgill所说,您无需检查甚至保存strncpy的返回值。

答案 1 :(得分:3)

我认为strncpy()功能不是你想要的。考虑一下这个电话:

strncpy(addr->name, name, MAX_DATA);

如果nameMAX_DATA个或更多字符,则会将name中的字节复制到addr->name,而不会 NUL - 终止目的地。您有两种常规选择:

  1. 使用

    等代码手动NUL终止结果
    addr->name[MAX_DATA-1] = '\0';
    

    但是,这很容易出错,因为每次都必须记住这样做。

  2. 使用诸如strlcpy()之类的库函数(通常在BSD派生的系统上可用,但不是标准的),它总是NUL终止目的地,即使源不完全适合。