简体   繁体   English

了解结构中字符串的动态内存分配

[英]Understanding dynamic memory allocation of a string within a struct

I have come across an instance where memory is allocated dynamically to a char pointer within a struct in a way that does not make much sense to me, but - of course - works. 我遇到了一个实例,其中动态地将内存分配给结构中的char指针,这种方式对我来说意义不大,但可以工作。 A similar question has been posted before. 之前已经发布过类似的问题 The answers, however, did not help me understand what is actually happening in the allocation process. 但是,答案并没有帮助我理解分配过程中实际发生的情况。

Here is the code example I found: 这是我发现的代码示例:

struct a_structure {
   char *str;
   struct a_structure *next;
};

Memory has been allocated in the following way: 内存已通过以下方式分配:

ptr_start=(struct a_structure *)malloc(sizeof (struct a_structure *));
...
char *some_words="How does this work?";
ptr_start->str=(char *)malloc(strlen(some_words)+1);
strcpy(ptr_start->str, some_words);
ptr_start->next=(struct a_structure *)malloc(sizeof(struct a_structure *));
...

I don't understand why malloc is used with the size of a pointer here. 我不明白为什么在这里将malloc与指针的大小一起使用。 ptr_start is a pointer of type struct a_structure . ptr_startstruct a_structure类型的指针。 That would mean it needs memory of size sizeof(struct a_structure) + the size of my string that hasn't been specified in the structure declaration. 这意味着它将需要大小为sizeof(struct a_structure)内存+结构声明中未指定的我的字符串的大小。 In the above example, however, malloc returns the address of yet another pointer pointing to a structure of type a_structure , am I right? 但是,在上面的示例中,malloc返回另一个指针的地址,该指针指向a_structure类型的结构,对吗?

Given that you have struct a_structure* ptr_start , this code is incorrect and does not work: 假设您具有struct a_structure* ptr_start ,则此代码不正确,因此不起作用:

ptr_start=(struct a_structure *)malloc(sizeof (struct a_structure *));

It should have been: 应该是:

ptr_start = malloc(sizeof *ptr_start);

The reason why it "seems to work" is because you invoked undefined behavior, and anything can happen. 之所以“看起来可行”,是因为您调用了未定义的行为,任何事情都可能发生。 The program could seem to work one moment, then crash at another time. 该程序似乎可以工作一会儿,然后在另一时间崩溃。

This does however just allocate the struct itself. 但是,这只是分配结构本身。 The pointers inside it will, like all pointers, point at memory allocated somewhere else. 像所有指针一样,它内部的指针将指向其他地方分配的内存。 The following code with malloc for the string and strcpy() is one way to do so. 以下带有malloc的字符串和strcpy()是一种实现方法。

The last line is however incorrect for the same reason as pointed out above. 但是,由于与上述相同的原因,最后一行是不正确的。

I don't understand why malloc is used with the size of a pointer here. 我不明白为什么在这里将malloc与指针的大小一起使用。 ptr_start is a pointer of type struct a_structure. ptr_start是类型为struct a_structure的指针。 That would mean it needs memory of size sizeof(struct a_structure) + the size of my string that hasn't been specified in the structure declaration 这意味着它需要的内存大小为sizeof(struct a_structure)+在结构声明中未指定的我的字符串的大小

You are right. 你是对的。 To create structure a_structure in order to manipulate it we need to allocate memory for whole structure. 要创建structure a_structure以便对其进行操作,我们需要为整个结构分配内存。 (Unless the object has been ALREADY created and for whatever reason we need a dynamically allocated pointer holding pointer to that object). (除非已经创建了对象,并且出于任何原因,我们都需要动态分配的指针来保存指向该对象的指针)。

but - of course - works. 但是-当然-可行。

The presented fragment of the program cannot work properly for the stated above reasons. 由于上述原因,程序的所提供片段无法正常工作。

In the above example, however, malloc returns the address of yet another pointer pointing to a structure of type a_structure, am I right? 但是,在上面的示例中,malloc返回另一个指针的地址,该指针指向a_structure类型的结构,对吗?

Yes, you are right. 是的,你是对的。

This is also problematic: 这也是有问题的:

ptr_start->next=(struct a_structure *)malloc(sizeof(struct a_structure *));

ptr_start->next can hold a pointer already. ptr_start->next可以已经包含一个指针。 We typically do not need to allocate a pointer here. 我们通常不需要在这里分配指针。 We would assign a pointer to the existing structure or we would allocate memory for the whole structure. 我们将为现有结构分配一个指针,或者为整个结构分配内存。

See example: 参见示例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct a_structure {
   char *str;
   struct a_structure *next;
};

struct a_structure * allocatePointer(void)
{
    // ptr ptrToObj1Allocated points to allocted memory which can hold a ponter   
    struct a_structure * ptrToObj1Allocated = malloc(sizeof (struct a_structure *)); 
    return ptrToObj1Allocated;
}

int main(){       
    // 1.
    struct a_structure obj1;    //  structure a_structure has been allocated on the stack 

    struct a_structure * ptrToObj1 = & obj1; // points to the existing structure

    char *some_words = "How does this work?";
    ptrToObj1->str = malloc(strlen(some_words)+1);
    if(ptrToObj1->str == NULL){printf("No enough memory\n"); return -1;}

    strcpy(ptrToObj1->str, some_words); // copy the string
    // now obj1 has its own copy of the string.

    // 2.
    // dynamically allocate another structure on the heap
    // we want to allocate memory for the structure not just a memory to keep the pointer to the structure.

    struct a_structure *obj2 = malloc( sizeof (struct a_structure));  // memory has been allocated to hold struct a_structure with 2 pointers
    if(obj2 == NULL){printf("No enough memory\n"); return -2;}

    char *words = "More words..";
    obj2->str = malloc(strlen(words)+1);
    if(obj2->str == NULL){printf("No enough memory\n"); return -3;}

    strcpy(obj2->str, words);  // copy the string

    obj2->next = ptrToObj1;    // points to the already existing object

     //----
    printf("String in obj1 is: %s\n", ptrToObj1->str);
    printf("String in obj2 is: %s\n", obj2->str);          
    printf("obj2->next points to structure with string: %s\n", obj2->next->str );  

    // free the allocated  memory:   
    free(ptrToObj1->str);

    free(obj2->str);     
    free(obj2);    

    return 0;
}

Output: 输出:

String in obj1 is: How does this work?
String in obj2 is: More words..
obj2->next points to structure with string: How does this work?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM