ç是否自动为我分配内存? [英] Does C allocate memory automatically for me?
问题描述
我一直在写℃,只有很少的几个星期,也没有花时间去担心自己太多关于的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 calledallocated 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 useregister
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屋!