堆对象如何使用堆栈中的数据?

时间:2016-03-31 15:21:32

标签: c pointers

我已经宣布struct foo是这样的:

struct foo {
    const char* name_lower; 
    const char* name_caps
    //..
};

我在堆上动态创建foo的实例,并希望在name_lowername_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];
}

我很担心,因为我不知道这段代码是否会崩溃。临时创建的数组lc将保存在堆栈中。一旦函数终止,堆栈将被清除,cl可能会消失。

这是否意味着foo实例将丢失其名称,即其引用?如果是这样,我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

继续评论,分配/复制和分配cstrdup的新内存块的起始地址的最简单方法是使用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_lowerentry->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数组。