【问题标题】:Understanding dynamic memory allocation of a string within a struct了解结构内字符串的动态内存分配
【发布时间】:2018-08-05 19:45:02
【问题描述】:

我遇到了一个实例,其中内存被动态分配给结构内的 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_startstruct a_structure 类型的指针。这意味着它需要大小为sizeof(struct a_structure) 的内存+ 未在结构声明中指定的我的字符串的大小。然而,在上面的例子中,malloc 返回另一个指向a_structure 类型结构的指针的地址,对吗?

【问题讨论】:

  • “我不明白为什么 malloc 在这里与指针大小一起使用” - 我明白。意思是作者写错了。可能是因为他们不经常写惯用的 C。
  • 我不明白为什么 malloc 在这里与指针大小一起使用。 ptr_start:我也没有,可能是错的,应该是sizeof (struct a_structure)。您在哪里找到该代码?
  • 顺便说一句,如果您阅读this Q&A,您将学习如何避免此类错误等等。
  • 我在 Jürgen Wolf 的一本名为“C von A bis Z”(德语)的关于 C 编程语言的书中发现了这一点。
  • 我猜作者不知道字母表。它是:B、BCPL、C、C++、D、Java、J++、C#。

标签: c pointers struct dynamic-memory-allocation


【解决方案1】:

我不明白为什么 malloc 在这里与指针的大小一起使用。 ptr_start 是 struct a_structure 类型的指针。这意味着它 需要 sizeof(struct a_structure) + my 大小的内存 结构声明中未指定的字符串

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

但是 - 当然 - 有效。

由于上述原因,显示的程序片段无法正常工作。

然而,在上面的例子中,malloc 返回的地址是 另一个指向 a_structure 类型结构的指针,我是 对吧?

是的,你是对的。

这也是有问题的:

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?

【讨论】:

    【解决方案2】:

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

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

    应该是:

    ptr_start = malloc(sizeof *ptr_start);
    

    它“似乎工作”的原因是因为您调用了未定义的行为,并且任何事情都可能发生。该程序可能会在某一时刻运行,然后在另一时刻崩溃。

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

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

    【讨论】:

    • 你能解释一下为什么你使用“sizeof *ptr_start”而不是“sizeof struct a_structure”吗?
    • @N.Krebs 意思是一样的。 *ptr_start 给出struct a_structure 类型的项目。 sizeof 的操作数没有被计算,所以此时指针指向任何地方都没有关系。这是确保使用正确类型的常用技巧,以避免您在此处遇到的那种错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多