有一个结构
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
}
是一个字符串文字。)
"foo1"
不再是字符串文字,而是在运行时确定长度的任意数组,该怎么办?const char* name
的签名不是Foo_init()
而Foo_init(struct Foo* foo, const char* name)
(即Foo_init(struct Foo* foo, char* name)
不再是char*
),该怎么办?const
/ malloc()
内存作为memcpy()
(或char*
的传入参数,或者在内存中拥有一堆元素的任何东西),假设我想要“存储”在int*
内?答案 0 :(得分:3)
哪种方式正确?
这取决于用例,但高度更喜欢第二。如果要将指向字符串文字的指针存储到name
,然后尝试修改其内容,则会导致未定义的行为。如果name
为const
,您只需要保存此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 *,或任何拥有一个 在内存中的一堆元素),假设我想在其中“存储它” 结构
当您不知道输入数据量并需要在运行时计算它时,您需要在堆上为动态存储持续时间分配内存。 自动阵列更安全&更快,所以如果你不必使用动态存储,不要。