There is no default value for your pointer. Your pointer will indicate what it currently stores. Since you did not initialize it, the line
newCell.subcells[i] = ...
Effectively accesses some undefined part of memory. Remember that subelements [i] are equivalent
*(newCell.subcells + i)
If there is garbage on the left side, you add i to the garbage value and gain access to memory in this undefined location. As you said correctly, you will need to initialize the pointer to point to some valid memory area:
newCell.subcells = malloc(bytecount)
After this line, you can access this number of bytes. As for other memory sources, there are different types of storage that everyone uses. What kind you get depends on what kind of object you have and what storage class you specify for the compiler.
malloc returns a pointer to an object without a type. You can point to a pointer to this memory area, and the type of the object will actually become the type of the specified type of object. The memory is not initialized with any value, and access is usually slower. Objects thus obtained are called allocated objects .- You can place objects around the world. Their memory will be initialized to zero. For points, you get NULL pointers; for floats, you also get zero zero. You can rely on the right starting value.
- If you have local variables, but use the
static class specifier, then you will have the same initial value rule as for global objects. Usually, memory is allocated in the same way as global objects, but this is by no means a necessity. - If you have local variables without a storage class specifier or with
auto , then your variable will be allocated on the stack (even if it is not defined by C, this is what compilers do, of course, of course). You can take its address, in which case the compiler will have to omit the optimization, for example, insert it into registers. - Local variables used with the
register storage class specifier are marked as having special storage. As a result, you can no longer use your address. Recent compilers usually do not need to use register more because of their complex optimizers. If you are truly an expert, then you can get some performance if you use it.
Objects have associated storage durations that can be used to display various initialization rules (formally they define only the lifespan of at least objects). Objects declared with auto and register have automatic storage durations and are not initialized. You must explicitly initialize them if you want them to contain some value. If you do not, they will contain everything that the compiler left on the stack before they begin life. Objects allocated by malloc (or another function of this family, for example calloc ) are allocated storage time. Their storage is also not initialized. An exception is the use of calloc , in which case the memory is initialized to zero ("real" zero, that is, all bytes 0x00, regardless of any representation of the NULL pointer). Objects declared using static and global variables have a static storage duration. Their memory is initialized to zero, corresponding to their type. Note that an object must not have a type, but the only way to get an object without a type is to use dedicated storage. (An object in C is a "storage area").
So what? Here is the fixed code. Because, as soon as you have allocated a block of memory, you can no longer get more, how many items you have allocated, it is best to always keep this account. I injected variale dim into the structure in which the account is stored.
Cell makeCell(int dim) { Cell newCell; newCell.subcells = malloc(dim * sizeof(*newCell.subcells)); newCell.dim = dim; for(int i = 0; i < dim; i++) { newCell.subcells[i] = makeCell(dim - 1); } return newCell; }
Now everything looks like this: dim = 2:
Cell { subcells => { Cell { subcells => { Cell { subcells => {}, dim = 0 } }, dim = 1 }, Cell { subcells => { Cell { subcells => {}, dim = 0 } }, dim = 1 } }, dim = 2 }
Note that in C, the return value of a function is not required to be an object. No storage is required at all. Therefore, you cannot change it. For example, the following is not possible:
makeCells(0).dim++
You will need a "free function" that will free up the allocated memory again. Because storage of selected objects is not automatically freed. You must call free to free this memory for each subcells pointer in your tree. This left an exercise for you to write it :)