简体   繁体   English

将指向结构数组的指针传递给 malloc 的 function

[英]Passing a pointer to an array of structs to a function for malloc

I've looked around and found answers on how to allocate memory properly for a 2D array with pointer notation, and I've found how to properly pass a 2d pointer array to a function, but I can't seem to combine the two steps.我环顾四周,找到了有关如何为带有指针表示法的二维数组正确分配 memory 的答案,并且我发现了如何正确地将二维指针数组传递给 function,但我似乎无法将这两个步骤结合起来.

So logically what I'm trying to do is allocate an array of pointers to structs.所以从逻辑上讲,我想做的是分配一个指向结构的指针数组。 What appears to be failing is trying to allocate memory似乎失败的是试图分配 memory

my code thus far:到目前为止我的代码:

typedef struct {
int tax, savings;
float salary;
} employee;

int readRecordFile(char* filename, Record*** array);

int main(void) {

employee** array;
int size;
char* file = "money.csv";
size = readRecordFile(file, &array);

FILE* fptr;
fptr = fopen(file, "r");


//Read the file into the the array 
for (int i = 0; i < size; i++) {
    fscanf(fptr, "%d,%d,%f", array[i]->tax, array[i]->savings, array[i]->salary);
}
fclose(fptr);


for (int i = 0; i < size; i++) {
    printf("%d, %d, %f\n", array[i]->tax, array[i]->savings, array[i]->salary);
}
return 0;
}

int readRecordFile(char* filename, employee*** array) {
//Function to open the file, malloc and initialize 2d arrays

//Open the file
FILE* fileptr;
fileptr = fopen(filename, "r");
if (fileptr == NULL) {
    printf("Failed to open file");
    exit(-1);
}

//Read first line of file (the size) and store to an int
int n;
fscanf(fileptr, "%d", &n);

//Initial malloc for the array of pointers
**array = malloc(n * sizeof(employee*)); //This is the line that throws the exception

//Malloc for each pointer in the array of pointers
for (int i = 0; i < n; i++) {
    *(array+i) = malloc(sizeof(employee));
}


//Close the file and return the size of the file
fclose(fileptr);

return n;
}

I have tried building a separate struct pointer within the function, then setting the regular pointer to it我尝试在 function 中构建一个单独的结构指针,然后将常规指针设置为它

    //Initial malloc for the array of pointers
employee **tester = malloc(n * sizeof(employee*));

//Malloc for each pointer in the array of pointers
for (int i = 0; i < n; i++) {
    *(tester+i) = malloc(sizeof(employee));
}

array = tester;

This method appears to fix the malloc issues, but the data printing in main fails.此方法似乎可以修复 malloc 问题,但在 main 中打印数据失败。

You are allocating the 2D array of struct correctly.您正在正确分配 struct 的二维数组。

But you are only reading into a 1D array of struct.但是您只是在读取结构的一维数组。 (eg array[i]->tax ) (例如array[i]->tax

To read a 2D array of struct you need 2 for loops要读取 struct 的 2D 数组,您需要 2 个 for 循环

for (int i = 0; i < size; i++) {
    for (int j=0; j< size; j++) { // in your case you have a size*size array, 
        fscanf(fptr, "%d,%d,%f", array[i][j]->tax, array[i][j]->savings, array[i][j]->salary);
     }
}

You need to decide whether you need a 1D or a 2D array.您需要决定是需要一维数组还是二维数组。

employee **array; is NOT an array, it is a single-pointer.不是数组,它是单指针。 ( pointer to pointer to employee ). 指向员工指针的指针)。

What is the value of size when you call:调用时size的值是多少:

for (int i = 0; i < size; i++) 

size is indeterminate (its value is whatever garbage value happens to be in memory at program startup). size是不确定的(它的值是程序启动时 memory 中的任何垃圾值)。 You invoke Undefined Behavior attempting to access the indeterminate value.您调用未定义的行为试图访问不确定的值。 size must be set before it is used (same for all variables) size必须在使用前设置(所有变量都相同)

At this same point, array is an uninitialized pointer , attempting to access an indeterminate address is just as bad.同时, array是一个未初始化的指针,试图访问一个不确定的地址同样糟糕。 (Remember, a pointer is simply a normal variable that holds the address of something else as its value). (请记住,指针只是一个普通变量,它保存其他东西的地址作为其值)。 Since the address held by array has not yet been assigned and no storage has been allocated for any employee struct, you cannot do:由于array持有的地址尚未分配,也没有为任何employee结构分配存储空间,因此您不能这样做:

fscanf(fptr, "%d,%d,%f", array[i]->tax, array[i]->savings, array[i]->salary);

Before you use array , you must:在使用array之前,您必须:

  1. allocate some number of pointers and assign the start of the memory block holding the allocated pointers to array , and then分配一些指针并分配 memory 块的开头,该块保存分配的指向array的指针,然后
  2. allocate storage for each of your struct and assign the starting address for each block of storage holding a struct to one of the pointers array[i] .为每个结构分配存储空间,并将每个存储结构块的起始地址分配给指针array[i]之一。

For example to initially declare 64 pointers, you could do:例如,最初声明 64 个指针,您可以这样做:

array = malloc (64 * sizeof *array);

( note: using the dereferenced pointer ( sizeof *array ) will always result in the correct type-size rather than trying to match the type, eg sizeof (employee*) ) 注意:使用取消引用的指针( sizeof *array )将始终导致正确的类型大小,而不是尝试匹配类型,例如sizeof (employee*)

ALWAYS validate every allocation, eg始终验证每个分配,例如

if (array == NULL) {            /* if the pointer returned by malloc is NULL */
    perror ("malloc-array");    /* issue diagnostic (perror is simple) */
    exit (EXIT_FAILURE);        /* handle error */
}

Now how to allocate for each struct?现在如何为每个结构分配? (the same way). (一样的方法)。 But, an approach that is much easier for reading, allocating and validating is to use a temporary struct with automatic storage and read and fill the temporary struct.但是,一种更容易读取、分配和验证的方法是使用具有自动存储功能的临时结构并读取和填充临时结构。 If your read succeeds, then allocate storage for your struct, assign the starting address for that block of memory to array[i] and then assign the contents of the temporary struct to your new block of memory.如果读取成功,则为结构分配存储空间,将 memory 块的起始地址分配给array[i] ,然后将临时结构的内容分配给 memory 的新块。 For example (after your fix size initialization):例如(在您的固定size初始化之后):

for (int i = 0; i < size; i++) {
    employee tmp = { .tax = 0 };    /* declare temporary struct, initialized zero */
    /* read values into temporary struct / VALIDATE every input */
    if (fscanf (fptr, "%d,%d,%f", tmp.tax, tmp.savings, tmp.salary) == 3) {
        array[i] = malloc (sizeof *array[i]);   /* allocate for struct */
        if (!array[i]) {                        /* validate allocation */
            perror ("malloc-array[i]");
            exit (EXIT_FAILURE); 
        }
        array[i] = tmp;             /* assign temp struct to allocated block */
    }
}

Now when you are done with using your "array", don't forget to free the memory allocated.现在,当您使用完“数组”后,不要忘记释放分配的 memory。 For example, assuming you validly filled size , then you could do:例如,假设您有效填充size ,那么您可以这样做:

for (int i = 0; i < size; i++)
    free (array[i]);            /* free each allocated struct */
free (array);                   /* free pointers */

There are probably additional errors in your posted code (it is in somewhat of a jumbled order), but these are the most immediate errors you are facing.您发布的代码中可能还有其他错误(它的顺序有点混乱),但这些是您面临的最直接的错误。 Make the changes and test further.进行更改并进一步测试。 Make sure all variables are properly initialized before their use.确保所有变量在使用前都已正确初始化。 Make sure you have allocated storage for each pointer you will use and then allocate for each struct assign the address for the struct storage to one of your allocated pointers.确保您已为将要使用的每个指针分配存储空间,然后为每个结构分配存储空间的地址,并将该结构存储空间的地址分配给您分配的指针之一。 If you hit another road block, either edit this question (or preferably ask a new question) noting the specific problem you are stuck on.如果您遇到另一个障碍,请编辑此问题(或最好提出一个新问题),注意您遇到的具体问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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