我已经宣布struct
foo是这样的:
struct foo {
const char* name_lower;
const char* name_caps
//..
};
我在堆上动态创建foo
的实例,并希望在name_lower
和name_caps
成员变量中保存一个值。这是由函数bar
void bar(foo* entry, const char* str, int delimiter_pos) {
char l[2] = {str[caps_pos-1], '\0'}; // create new string
char c[2] = {str[caps_pos+1], '\0'};
entry->name_lower = &l[0]; // assign these strings the foo instance
entry->name_caps = &c[0];
}
我很担心,因为我不知道这段代码是否会崩溃。临时创建的数组l
和c
将保存在堆栈中。一旦函数终止,堆栈将被清除,c
和l
可能会消失。
这是否意味着foo
实例将丢失其名称,即其引用?如果是这样,我该如何解决这个问题?
答案 0 :(得分:1)
继续评论,分配/复制和分配c
和strdup
的新内存块的起始地址的最简单方法是使用string.h
(来自{{1} }}):
void bar(foo* entry, const char* str, int delimiter_pos) {
char l[2] = {str[caps_pos-1], '\0'}; // create new string
char c[2] = {str[caps_pos+1], '\0'};
entry->name_lower = strdup (l); // assign these strings the foo instance
entry->name_caps = strdup (c);
}
在不再需要时,不要忘记free
分配给entry->name_lower
和entry->name_caps
的内存。
答案 1 :(得分:0)
您应该使用char *l = (char *)malloc(2 * sizeof(char));
然后初始化它;同样适用于char *c
。然后设置entry->name_lower = l; entry->name_caps = c;
分配时,请确保检查分配是否成功,即malloc
是否返回非NULL地址。
请确保在您不再需要内存后释放内存:free(entry->name_lower); free(entry->name_caps);
。
答案 2 :(得分:0)
它不会丢失任何东西。 struct
中的指针将保留其值,但内容将发生变化,最终您将获得SIGSEGV。
要使char *
保持不变,您还需要在堆上分配它。
void bar(foo* entry, const char* str, int delimiter_pos) {
char * l = malloc(2);
char * c = malloc(2);
/* Check l and c for NULLs */
l[0] = str[caps_pos-1];
l[1] = '\0';
c[0] = str[caps_pos+1];
c[1] = '\0';
entry->name_lower = l;
entry->name_caps = c;
}
请记住,当您不再需要时,您还应该free()
结构成员。
答案 3 :(得分:0)
如果您对字符串的长度有限制,则可以使用char
数组而不是指针。在您的示例中,所有字符串的长度均为1.假设您的字符串不能超过该字符串,则可以使用char[2]
代替char*
:
struct foo {
char name_lower[2];
char name_caps[2];
//..
};
void bar(foo* entry, const char* str, int delimiter_pos) {
entry->name_lower[0] = str[caps_pos-1];
entry->name_lower[1] = '\0';
entry->name_caps[0] = str[caps_pos+1];
entry->name_caps[1] = '\0';
}
历史记录:
因为这很容易使用,人们已经习惯了这一点,并强制对字符串长度进行人为限制,导致缓冲区溢出。如果您的字符串不受限制,请使用动态分配而不是char
数组。