简体   繁体   中英

How should I properly malloc an array of struct?

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <tchar.h>
#include <string.h>
#include <math.h>


HANDLE wHnd;    // Handle to write to the console.
HANDLE rHnd;    // Handle to read from the console.


struct Terra {
    int status;
    CHAR_INFO display;

};
int main(){
    int countX = 0;
    int countY = 0;
    int total = 0;
    CHAR_INFO ScreenCon[10000];
    int localcount = 0;

    struct Terra *world= malloc(10000*sizeof(*world));
...

I have been using visual studio programing a screen console program that generate and display an 100 x 100 CHAR_INFO array. without using malloc() . My code is referenced from Ben Ryves' windows console tutorial .

The code without malloc() function is:

struct Terra world[100][100];

This code works perfectly but the compiler warns me that I should allocate memory for it. So I tried to integrated memory allocation in it and I learned that malloc() can't allocate 2d array directly, I can only do so by dividing my chunk of memory into 100 parts and use 1 extra array to store their location, my solution is to revert that 2d array into 1d and handle the data location with extra code. However, with reference to other question in stack overflow, I have change my code to the one above. But I got error code E0144 and C2440 at line 28, what have I done wrong?

Isn't that code is supposed to created a new pointer of struct Terra who called world then allocate 10000 x the size of single Terra is for it? How should I initialize an pointer before its declared??

I have read some information about malloc() but seem I don't understand how this really work. I would like to know what I have done wrong.

PS: I have done more tests and it seems the problem is that malloc() statement:

struct Terra {
    int status;
    CHAR_INFO display;
};
int main()
{
    struct Terra* world = malloc(10000 * sizeof(*world));
    return 0;
}

This code also returns the same error.

So, you want to have the equivalent of struct Terra world[100][100]; , but allocated with malloc rather than having it on the stack, right?

I assume you know that you can allocate hundred objects of type foo like this:

foo *bar = malloc(100* sizeof(*bar));

bar is now a pointer to the first element of an array of 100 foo .

So in the world 2d array above you have an array of arrays of struct Terra of length 100. Basically, foo is an array of 100 struct world :

typedef struct Terra foo[100];

You can now allocate 100 of those arrays:

foo *world =  malloc(100* sizeof(*world));

World now points to the first array of 100 struct Terra of 100 such arrays

Naturally, this can be done without a typedef :

struct Terra (*world)[100] =  malloc(100* sizeof(*world));

I know this text may be a confusing mess of "arrays of arrays" but I hope you get the point.

Just an added comment on using malloc . When doing allocations like this: malloc(count * sizeof(*something)) , be sure to make sure that the multiplication doesn't overflow. One of the biggest security bugs in the java virtual machine, was a failure to do such a check.

Correct/Valid solution:

If you want to access/iterate the 2D array like it got declared like struct Terra world[100][100];

Then you can alloc 100 diferent arrays, like this, and

struct Terra **world= malloc(100*sizeof(Terra*));
for(int i=0; i<100;i++){
    world[i] = malloc(100*sizeof(Terra));
}

//the "usual" way to access the indexes
for(int i=0; i<100;i++)
    for(int j=0; j<100;j++)
        printf("%d ", world[i][j].status);

But if you want to use a singles continuous chunk o memory, you must allocate it like a 1D array, and access it doing some simple math:

size_t total_size = 100*100  //100 and 100 are the dimensions
struct Terra *world= malloc(total_size*sizeof(Terra));

//this way to access the indexes
for(int i=0; i<100;i++){
    for(int j=0; j<100;j++){
        //the formula to convert 2D indexes to a 1D array is: (i*N)+j, where N = number_of_columns
        printf("%d ", world[i*100 + j].status); 
    }
}

wrong old answer

struct Terra **world= malloc(100*100*sizeof(Terra));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM