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

Understanding dynamic memory allocation of a string within a struct

我遇到过一个实例,其中内存以一种对我来说没有多大意义的方式动态分配给结构中的 char 指针,但是 - 当然 - 有效。 similar question 之前已经发过。然而,答案并没有帮助我理解分配过程中实际发生的事情。

这是我找到的代码示例:

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

已按以下方式分配内存:

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 *));
...

我不明白为什么malloc这里用的是指针的大小。 ptr_start 是一个 struct a_structure 类型的指针。这意味着它需要大小为 sizeof(struct a_structure) + 结构声明中未指定的字符串大小的内存。然而,在上面的示例中,malloc returns 指向类型 a_structure 的另一个指针的地址,对吗?

鉴于您有 struct a_structure* ptr_start,此代码不正确且不起作用:

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

应该是:

ptr_start = malloc(sizeof *ptr_start);

之所以"seems to work"是因为你调用了未定义的行为,任何事情都有可能发生。该程序可能暂时运行正常,然后在另一时间崩溃。

然而,这只是分配结构本身。它里面的指针,就像所有的指针一样,指向分配在别处的内存。以下代码使用 malloc 作为字符串,使用 strcpy() 是一种方法。

然而,出于与上述相同的原因,最后一行是不正确的。

I don't understand why malloc is used with the size of a pointer here. ptr_start is a pointer of type 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

你是对的。要创建 structure a_structure 以便对其进行操作,我们需要为整个结构分配内存。 (除非对象已经被创建,并且出于某种原因我们需要一个动态分配的指针来保存指向该对象的指针)。

but - of course - works.

由于上述原因,所提供的程序片段无法正常运行。

In the above example, however, malloc returns the address of yet another pointer pointing to a structure of type a_structure, am I right?

是的,你是对的。

这也是有问题的:

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

ptr_start->next 已经可以容纳一个指针了。我们通常不需要在这里分配指针。我们将分配一个指向现有 结构,否则我们会为整个结构分配内存。

参见示例:

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

输出:

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?