何时将malloc()内存用于struct中的数组

时间:2017-08-17 21:33:15

标签: c arrays pointers struct

有一个结构

struct Foo{
    int a, b, c;
    char* name;
};

使用初始化函数

Foo_init(struct Foo* foo, const char* name){
    // ... stuff
}

当我创建struct Foo对象时,我传入const char*,作为对象的名称。例如:

struct Foo foo1;
Foo_init(&foo1, "foo1");

目标是将"foo1"的内容“存储”到foo1的{​​{1}}变量中。

我目前正在这样做:

char*

但我想知道正确的方法是否正确:

Foo_init(struct Foo* foo, const char* name){
    foo->name = name;

    // ... other stuff
}

(我想两种方式都可以,因为在这个例子中,参数Foo_init(struct Foo* foo, const char* name){ int name_len = strlen(name) + 1; foo->name = malloc(name_len); memcpy(foo->name, name, name_len) // ... other stuff } 是一个字符串文字。)

  1. 哪种方式正确?
  2. 如果参数"foo1"不再是字符串文字,而是在运行时确定长度的任意数组,该怎么办?
  3. 如果const char* name的签名不是Foo_init()Foo_init(struct Foo* foo, const char* name)(即Foo_init(struct Foo* foo, char* name)不再是char*),该怎么办?
  4. 更一般地说,时我需要const / malloc()内存作为memcpy()(或char*的传入参数,或者在内存中拥有一堆元素的任何东西),假设我想要“存储”在int*内?

1 个答案:

答案 0 :(得分:3)

  

哪种方式正确?

这取决于用例,但高度更喜欢第二。如果要将指向字符串文字的指针存储到name,然后尝试修改其内容,则会导致未定义的行为。如果nameconst,您只需要保存此string而不进行修改,则可以先使用。

一种常见的技术是将string文字放入“只读数据”部分,该部分以只读方式映射到进程空间(这就是为什么你可以不改变它。它确实因平台而异。

  

如果参数const char * name不再是字符串文字,该怎么办?   但是在运行时确定长度的任意数组?

无所谓,它会是一样的。如果其string(空终止字符序列),strlen将返回字符数,您可以将其复制到heap上的malloced内存。

  

如果Foo_init()的签名不是Foo_init(struct Foo * foo,   const char * name)但是Foo_init(struct Foo * foo,char * name)(即   char *不再是const)?

不再是const。它允许您修改数组的内容。既然你不需要修改它(它是init函数),你应该保留它const

  

更一般地说,我什么时候需要malloc()/ memcpy()内存   传入的参数是一个char *(或一个int *,或任何拥有一个   在内存中的一堆元素),假设我想在其中“存储它”   结构

当您不知道输入数据量并需要在运行时计算它时,您需要在堆上为动态存储持续时间分配内存。 自动阵列更安全&更快,所以如果你不必使用动态存储,不要。