分配和重新分配结构及其元素

时间:2015-08-13 11:05:06

标签: c pointers memory-management struct dynamic-memory-allocation

我有一些关于为结构及其成员分配内存的问题。

假设我有这样的结构:

struct _MyStruct
{
    char *a;
}
typdef struct _MyStruct MyStruct;
  1. 我想要' a'成为一个动态字符串,我想为它分配内存。在这种情况下,我是否应该为MyStruct分配内存?例如:

    MyStruct *myStr = malloc(sizeof(MyStruct)); //necessary?
    MyStruct *myStrCopy = myStr;
    myStrCopy->a=malloc(sizeof(char));
    //checking for null//
    
  2. 现在假设我为结构(myStr)分配了一定量的内存。现在,当我将内存分配给' a'时,是在分配给myStr的内存中分配的内存,还是它会获得一个新的内存块?

  3. 我可以为' a'分配更多内存。比我分配到myStr?

  4. 假设我想放大' a'与realloc()。我应该先放大myStr吗?如果我这样做,那么记忆量是多少(sizeof(myStr)*size_of_my_string)

4 个答案:

答案 0 :(得分:3)

  
      
  1. 我想'a'是一个动态字符串,我想为它分配内存。在这种情况下,我是否应该将内存分配给MyStruct?
  2.   

嗯,你的MyStruct总是需要存在,但有几种方法可以做到这一点,你应该选择最适合你用例的方法。

基本方法:

MyStruct myStr;
myStr.a = malloc(N); // "N chars please!"

// You can still get a pointer to this object:
foo(&myStr);

// Don't forget to free the `char` buffer later
free(myStr.a);

动态分配 - 有效,但不是必需的:

MyStruct* myStr = malloc(sizeof(MyStruct));
myStr->a = malloc(N); // "N chars please!"

// It's already a pointer, so:
foo(myStr);

// Don't forget to free the `char` buffer later
free(myStr->a);

// And then the struct
free(myStr);
  
      
  1. 现在假设我为结构(myStr)分配了一定量的内存。现在,当我将内存分配给'a'时,是分配给myStr的内存中分配的内存,还是它获得了一块新内存?
  2.   

这是一个新的块。

每个动态分配的内存块都是完全独立的。当您将成员变量a作为指针时,您确保虽然a存在于结构中,但它指向的东西却没有(除非您指向它自己,lol)。

myStr (or *myStr):                       your malloc'd memory:

0          32                       0   8   16   24   32   40  ...
+----------+                        +------------------------------+
| char* a——|———————————————————————→| text or whatever here        |
+----------+                        +------------------------------+
 (somewhere in memory)                 (somewhere else in memory)

无论您构建myStr的哪种方式,上图都是有效的。

  
      
  1. 我可以为'a'分配比分配给myStr更多的内存吗?
  2.   

是的,无论你想要什么。它是分开的。你有间接

  
      
  1. 假设我想用realloc()放大'a'。我应该先放大myStr吗?如果我这样做,那么内存量是多少(sizeof(myStr)* size_of_my_string)?
  2.   

没有

答案 1 :(得分:2)

只是为了澄清: myStra只是指向某个内存位置的指针。这并不意味着他们共享相同的内存位置。

因此,分配myStra并不是在增加自己的变量。 它在进程的虚拟内存空间中的某处请求新内存,并将地址存储在相应的指针中。

所以回答你的问题:是的你可以为a分配一个大于myStr的内存。

更新以获得更好的说明:

 0x000 | 0x004 | 0x008 | 0x0012 | 0x0016
   ^                                 ^
   |                                 |
   myStr                             a

所以myStr可能位于内存中,与a相比完全不同。

答案 2 :(得分:1)

不需要为structure分配。只需要char *即可。说

MyStruct str;

str.a = malloc( sizeof(char)*10);

str将在堆栈中。记忆指出' a'将在堆中。因此当str超出范围时,对象将被破坏。但不是动态分配的一个由' a'指向的。我们已手动删除它。 结构的大小将是相同的,并且会随着动态内存的大小而变化。' a'

只需重新分配' a'。

指向的内存
str.a = realloc(a, sizeof(char)*20);

答案 3 :(得分:0)

  1. 第一种情况

    MyStruct *myStr = malloc(sizeof(MyStruct)); //necessary?
    
    是的,非常。如果没有首先分配到myStr,尝试取消引用myStr(到达a)是undefined behaviour ..此外,FWIW,

    myStrCopy->a=malloc(sizeof(char));
    

    仅为一个char分配内存,请确保这是您真正想要的内容。如果你真的想要那个,那么你可以把它重写为

    myStrCopy->a=malloc(1);
    

    sizeof(char)保证为1中的C

  2. 如果成功,通过malloc()和家人的每次分配都会为您提供新的记忆。

  3. 你可以,你应该。实际上没有任何关系。它们是单独的变量,需要单独的内存分配。

  4. 不,只有realloc()上的a就足够了。