ç是否自动为我分配内存? [英] Does C allocate memory automatically for me?

查看:142
本文介绍了ç是否自动为我分配内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在写℃,只有很少的几个星期,也没有花时间去担心自己太多关于的malloc()。不过,最近我的一个程序返回幸福的笑脸,而不是我所预料的真/假值的字符串吧。

I have been writing C for only a scant few weeks and have not taken the time to worry myself too much about malloc(). Recently, though, a program of mine returned a string of happy faces instead of the true/false values I had expected to it.

如果我创建一个结构是这样的:

If I create a struct like this:

typedef struct Cell {
  struct Cell* subcells;
}

再后来初始化像这样

and then later initialize it like this

Cell makeCell(int dim) {
  Cell newCell;

  for(int i = 0; i < dim; i++) {
    newCell.subcells[i] = makeCell(dim -1);
  }

  return newCell; //ha ha ha, this is here in my program don't worry!
}

我是不是要结束了访问存储在内存中某个幸福的笑脸,或者写在previously现有细胞,还是什么?我的问题是,如何Ç分配内存时,我有没有真正的malloc()的内存适量?什么是默认?

Am I going to end up accessing happy faces stored in memory somewhere, or perhaps writing over previously existing cells, or what? My question is, how does C allocate memory when I haven't actually malloc()ed the appropriate amount of memory? What's the default?

推荐答案

有是您的指针没有默认值。您的指针会指向不管它当前存储。由于您没有初始化它,行

There is no default value for your pointer. Your pointer will point to whatever it stores currently. As you haven't initialized it, the line

newCell.subcells[i] = ...

有效地访问内存的一些不确定的一部分。请记住,子电池[i]为等价于

Effectively accesses some uncertain part of memory. Remember that subcells[i] is equivalent to

*(newCell.subcells + i)

如果左侧包含一些垃圾,你最终会加入 I 来一个垃圾值,并在此不确定位置访问内存。正如你说正确,你将不得不初始化指针指向一些有效的内存区域:

If the left side contains some garbage, you will end up adding i to a garbage value and access the memory at that uncertain location. As you correctly said, you will have to initialize the pointer to point to some valid memory area:

newCell.subcells = malloc(bytecount)

这行后,您可以访问多个字节。至于内存的其他来源,有不同类型的存储,所有有其用途。什么样的你要看你有什么样的对象和存储类你告诉编译器使用。

After which line you can access that many bytes. With regards to other sources of memory, there are different kind of storage that all have their uses. What kind you get depends on what kind of object you have and which storage class you tell the compiler to use.


  • 的malloc 返回一个指针没有类型的对象。可以使一个指针指向的内存区域,和对象的类型将有效成为尖的对象类型的类型。存储器未初始化为任意值并访问通常比较慢。对象,因此获得的名为分配对象

  • 您可以在全球范围将物体。他们的记忆将被初始化为零。对于点,你会得到NULL指针,因为花车你会得到一个合适的也为零。你可以依靠适当的初始值。

  • 如果您有局部变量,而是使用静态存储类说明,那么你将有相同的初始值作为统治全球的对象。该内存通常被分配像全局对象以相同的方式,但这是没有办法的必需品。

  • 如果您有局部变量没有任何存储类说明或汽车,那么你的变量将被堆栈(即使不是用C定义,因此在分配,这是什么编译器实际上做当然)。你可以把它在这种情况下,编译器将不得不省略像优化将其放入当然寄存器地址。

  • 与存储类说明使用注册局部变量,被标记为具有特殊的存储。其结果是,你不能把它的地址了。在最近的编译器,通常没有必要使用注册了,因为其复杂的优化器。如果你真的专家,那么你可能会得到一些表现出来,如果​​使用它,虽然。

  • malloc returns a pointer to an object with no type. You can make a pointer point to that region of memory, and the type of the object will effectively become the type of the pointed to object type. The memory is not initialized to any value and access usually is slower. Objects so obtained are called allocated objects.
  • You can place objects globally. Their memory will be initialized to zero. For points, you will get NULL pointers, for floats you will get a proper zero too. You can rely on a proper initial value.
  • If you have local variables but use the static storage class specifier, then you will have the same initial value rule as for global objects. The memory usually is allocated the same way like global objects, but that's in no way a necessity.
  • If you have local variables without any storage class specifier or with auto, then your variable will be allocated on the stack (even though not defined so by C, this is what compilers do practically of course). You can take its address in which case the compiler will have to omit optimizations like putting it into registers of course.
  • Local variables used with the storage class specifier register, are marked as having a special storage. As a result, you cannot take its address anymore. In recent compilers, there is normally no need to use register anymore, because of their sophisticated optimizers. If you are really expert, then you may get some performance out of it if using it, though.

对象具有相关联的,可用于显示不同的初始化规则(正式地说,它们只定义多久至少物体住)存储的持续时间。与汽车注册申报对象具有自动存储时间并的的初始化。你如果你希望它们包含一些价值显式初始化它们。如果你不这样做,它们将包含任何留在堆栈上的编译器又开始之前一辈子。由的malloc (或家族的另一功能,如释放calloc )分配对象已分配的存储时间。他们的存储的的任何初始化。使用释放calloc ,在这种情况下,内存初始化时的一个例外是零(真正的零,即所有字节0x00时,不考虑任何NULL指针重新presentation)。该声明与静态和全局变量对象具有静态存储持续时间。其存储的的初始化为零适合他们各自的类型。注意,对象一定不能有型,但只有这样,才能得到一个类型较少的对象是使用分配的存储空间。 (在C中的对象是的存储区域)。

Objects have associated storage durations that can be used to show the different initialization rules (formally, they only define how long at least the objects live). Objects declared with auto and register have automatic storage duration and are not initialized. You have to explicitly initialize them if you want them to contain some value. If you do not, they will contain whatever the compiler left on the stack before they began lifetime. Objects that are allocated by malloc (or another function of that family, like calloc) have allocated storage duration. Their storage is not initialized either. An exception is when using calloc, in which case the memory is initialized to zero ("real" zero. i.e all bytes 0x00, without regard to any NULL pointer representation). Objects that are declared with static and global variables have static storage duration. Their storage is initialized to zero appropriate for their respective type. Note that an object must not have a type, but the only way to get a type-less object is using allocated storage. (An object in C is a "region of storage").

那么,什么是什么呢?这里是固定的code。因为一旦你分配的内存,你可以不回来了,你分配多少商品的块,最好是永远商店算什么地方。我介绍一个variale 暗淡来,获取存储的计数的结构。

So what is what? Here is the fixed code. Because once you allocated a block of memory you can't get back anymore how many items you allocated, best is to always store that count somewhere. I've introduced a variale dim to the struct that gets the count stored.

Cell makeCell(int dim) {
  /* automatic storage duration => need to init manually */
  Cell newCell;

  /* note that in case dim is zero, we can either get NULL or a 
   * unique non-null value back from malloc. This depends on the
   * implementation. */
  newCell.subcells = malloc(dim * sizeof(*newCell.subcells));
  newCell.dim = dim;

  /* the following can be used as a check for an out-of-memory 
   * situation:
   * if(newCell.subcells == NULL && dim > 0) ... */
  for(int i = 0; i < dim; i++) {
    newCell.subcells[i] = makeCell(dim - 1);
  }

  return newCell;
}

现在,事情是这样的昏暗= 2:

Now, things look like this for dim=2:

Cell { 
  subcells => { 
    Cell { 
      subcells => { 
        Cell { subcells => {}, dim = 0 }
      }, 
      dim = 1
    },
    Cell { 
      subcells => { 
        Cell { subcells => {}, dim = 0 }
      }, 
      dim = 1
    }
  },
  dim = 2
}

请注意,在C,不需要一个函数的返回值是一个对象。完全没有存储需要存在。因此,你不能改变它。例如,以下是不可能的:

Note that in C, the return value of a function is not needed to be an object. No storage at all is required to exist. Consequently, you are not allowed to change it. For example, the following is not possible:

makeCells(0).dim++

您将需要一个免费功能,自由的再次分配的内存。由于存储分配的对象不会自动释放。你必须调用免费来释放在你的树中的每个子单元指针内存。它作为一个练习为你写了:)

You will need a "free function" that free's the allocated memory again. Because storage for allocated objects is not freed automatically. You have to call free to free that memory for every subcells pointer in your tree. It's left as an exercise for you to write that up :)

这篇关于ç是否自动为我分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆