简体   繁体   English

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

[英]How can heap objects use data from the stack?

I've declared the struct foo like this:我已经像这样声明了struct foo:

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

I dynamically create instances of foo on the heap and want to save a value in the name_lower and name_caps member variable.我在堆上动态创建foo实例,并希望在name_lowername_caps成员变量中保存一个值。 This is done by the function bar这是由功能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];
}

I am worried, because I don't know if this code is going to crash.我很担心,因为我不知道这段代码会不会崩溃。 The temporarily created arrays l and c will be saved on the stack.临时创建的数组lc将保存在堆栈中。 Once the function terminates the stack will be cleared up and c and l will probably disappear.一旦函数终止,堆栈将被清除并且cl可能会消失。

Does this mean that the foo instance will lose its names, ie its references?这是否意味着foo实例将丢失其名称,即其引用? If so, how can I solve this problem?如果是这样,我该如何解决这个问题?

Continuing from the comment, the easiest way to allocate/copy and assign the start address for new blocks of memory for l and c is to use strdup (from string.h ):继续注释,为lc新内存块分配/复制和分配起始地址的最简单方法是使用strdup (来自string.h ):

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);
}

Don't forget to free the memory allocated to entry->name_lower and entry->name_caps when no longer needed.不要忘记在不再需要时free分配给entry->name_lowerentry->name_caps的内存。

You should instead use char *l = (char *)malloc(2 * sizeof(char));你应该改用char *l = (char *)malloc(2 * sizeof(char)); and then initialize it;然后初始化它; similarly for char *c .同样对于char *c Then set entry->name_lower = l; entry->name_caps = c;然后设置entry->name_lower = l; entry->name_caps = c; entry->name_lower = l; entry->name_caps = c;

When allocating make sure you check whether the allocation succeeded, ie whether malloc returned non-NULL address.分配时一定要检查分配是否成功,即malloc是否返回了非NULL地址。

Make sure you free the memory after you don't need it anymore: free(entry->name_lower); free(entry->name_caps);确保在不再需要内存后释放内存: free(entry->name_lower); free(entry->name_caps); free(entry->name_lower); free(entry->name_caps); . .

It will not lose anything.它不会失去任何东西。 The pointers in the struct will retain their value, but the content will change and you will eventually get SIGSEGV. struct的指针将保留其值,但内容会发生变化,您最终将获得 SIGSEGV。

For the char * to persist, you need to allocate it on the heap too.为了让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;
}

Remember that you should also free() the struct members when you will no longer need it.请记住,当您不再需要结构成员时,您还应该free()结构成员。

If you have a limit on the length of your strings, you can use char arrays instead of pointers.如果您对字符串的长度有限制,则可以使用char数组而不是指针。 In your example, all strings have a length of 1. Assuming your strings cannot be longer than that, you can use char[2] instead of 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';
}

Historical note:历史记录:

Because this is so easy to use, people got accustomed to this, and forced artificial limits on string length, leading to buffer overflows.由于它非常易于使用,人们习惯了这一点,并强制人为地限制字符串长度,导致缓冲区溢出。 If your strings are not limited, use dynamic allocation instead of char arrays.如果您的字符串不受限制,请使用动态分配而不是char数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 访问堆中的数据比访问栈中的数据快吗? - Is accessing data in the heap faster than from the stack? C:将数据从堆复制到堆栈的成本? - C : cost of copying data from heap to stack? 如何使用 gdb 探索堆栈/堆? - how to use gdb to explore the stack/heap? 通过设置取消引用的指针将对象从堆栈复制到堆是一种好习惯吗? - Is it good practice to copy objects from the stack to the heap by setting a dereferenced pointer? 对于 C 程序过程,我如何知道 memory 中数据、堆栈和堆的起始地址及其大小? - How can I know the starting address of data,stack and heap, and their sizes in memory for a C program process? 将数据存储在堆中之后,如何将其存储在结构中而不会出现堆栈溢出? - After storing data in heap, how can I store it in struct without stack overflow? 如何保存堆栈和堆 - How to save stack and heap 如何检测内存是否来自堆栈? (不是堆或静态变量) - How to detect if memory is from the stack? (not heap or a static variable) 如何将元素从分配在堆栈中的空指针数组转移到堆? - How to transfer elements from a void pointer array allocated in the stack to the heap? 堆栈、堆中的内存是如何排列的? - How is memory arranged in stack, heap?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM