在C中分配结构的字符串字段

时间:2016-11-04 15:10:06

标签: c pointers struct malloc c-strings

我尝试使用包含字符串的结构编写程序:

typedef struct s_conf
{
    char *shell1;
    char *shell2;
    char *shell3;
    char *shell4;
    char *server_ip;    
} t_conf;

每行解析一个配置文本文件行,我得到这些信息并将其存储到诸如line1和line4之类的变量中。现在我想为结构字段分配变量line1和line4的值:

char *line1 = "/var/www/host/current/app/console robot:file";
char *line4 = "192.168.00.00";

t_conf *conf;
if ((conf = malloc(sizeof(t_conf))) == NULL)
        {
            fprintf(stderr, "Malloc error\n");
            return (-1);
        }

strcpy(conf->shell1, line1);
strcpy(conf->server_ip, line4);

printf("line1 : '%s'\n"; line1);
printf("line4 : '%s'\n"; line4);

printf("t_conf->shell1 : '%s'\n", conf->shell1);
printf("t_conf->server_ip : '%s'\n", conf->server_ip);

输出:

line1 : '/var/www/host/current/app/console robot:file'
line4 : '192.168.00.00'
t_conf->shell1 : '/var/www/host/current/app'
t_conf->server_ip : '192.168.00.00'

如何正确分配c字符串t_conf-> shell1? 我尝试其他函数,如memcpy(),strdup(),并使用malloc:t_conf->shell1 = malloc(strlen(line1) + 1)分配变量,但它给了我相同的结果,我丢失了一部分line1?

2 个答案:

答案 0 :(得分:1)

strcpy(conf->shell1, line1);

您需要空间来存储line1

此外(正如评论中的@cat所指出的)strcpy是危险的,必须在生产代码中避免,替代方案是strdup(非标准)或snprintf:< / p>

size_t size = strlen(line1) + 1;
conf->shell1 = malloc(size);
snprintf(conf->shell1, size, "%s", line1);

当不再需要空格时,该空格应与free(conf->shell1);一起返回。

conf->server_ip

相同

请注意,如果您不需要修改这些字符串,则无需复制,只需指定:

conf->shell1 = line1;

答案 1 :(得分:1)

  

我尝试使用包含字符串的结构编写程序:

下面的

struct s_conf包含5个指针。它不包含任何字符串。对于C标准库,字符串是一个数组字符,包括最终的空字符('\0')。为了让你的代码工作,需要这些数组的内存 - 某个地方。

typedef struct s_conf {
    char *shell1;
    char *shell2;
    char *shell3;
    char *shell4;
    char *server_ip;    
} t_conf;

strcpy(conf->shell1, line1);失败,因为conf->shell1还没有指向副本可用内存的值。

使用指向包含所需数据的内存的值填充这5个指针。

// allocate memory for the structure
conf = malloc(sizeof *conf);
assert(conf);

// Simply copy the pointer if `line1` will exist for as long as `conf`.
conf->shell1 = line1;

// or
// Create an allocated copy.
conf->shell1 = strdup(line1);
// With this method, be sure to free the memory before freeing conf
...
free(conf->shell1);
free(conf);

strdup()不是标准库函数,但很常见。如果需要,提供相应的。示例:(根据您的需要定制)

char *my_strdup(const char *s) {
  if (s) {
    size_t sz = strlen(s) + 1;
    char *dest = malloc(sz);
    if (dest) {
      return memcpy(dest, src, sz);
    }
  }
  return NULL;
}