【问题标题】:Using a pointer to an array of structs does not return the complete array使用指向结构数组的指针不会返回完整的数组
【发布时间】:2021-11-30 10:45:11
【问题描述】:

我有一个主程序,它应该通过调用函数来加载数据(结构数组,未定义大小)、正确的数据,然后继续处理它。

以下是我正在尝试做的一个小例子。函数loadData接收指向主指针的指针,从而可以通过malloc为主指针分配一部分内存。数据在loadData 函数中加载和打印。但是当它返回 main 时,它只显示结构数组的第一项的正确内容。第二项是垃圾。

#include <stdio.h>
#include <stdlib.h>

typedef struct
{ 
    int dni;
    char cat;
    int weight;
} boxers;

void loadData(boxers *(*xbox), int *xcount)
{
    printf("How many boxers? ");
    scanf("%d", xcount);

    *xbox = (boxers *) malloc(sizeof(boxers) * (*xcount));

    for (int i = 0; i < (*xcount); i++)
    {
        printf("Provide the DNI for boxer number %d: ", i);
        scanf("%d", &xbox[i]->dni);
        printf("Provide the Category for boxer number %d: ", i);
        scanf(" %c", &xbox[i]->cat);
        printf("Provide the Weight for boxer number %d: ", i);
        scanf("%d", &xbox[i]->weight);
    }

    // First print the result of data loading
    for (int i = 0; i < *xcount; i++)
    {
        printf("DNI for boxer number %d, is: %d \n", i, xbox[i]->dni);
        printf("Category for boxer number %d, is: %c \n", i, xbox[i]->cat);
        printf("Weight for boxer number %d, is: %d \n", i, xbox[i]->weight);
    }

}

int main()
{
    boxers *box;
    int count;

    loadData(&box, &count);

    // Second print the result of data loading
    printf("\n\n");
    for (int i = 0; i < count; i++)
    {
        printf("DNI for boxer number %d, is: %d \n", i, box[i].dni);
        printf("Category for boxer number %d, is: %c \n", i, box[i].cat);
        printf("Weight for boxer number %d, is: %d \n", i, box[i].weight);
    }

    free(box);
    
    return 0;
}

控制台输出如下:

How many boxers? 2
Provide the DNI for boxer number 0: 123
Provide the Category for boxer number 0: A
Provide the Weight for boxer number 0: 45
Provide the DNI for boxer number 1: 789
Provide the Category for boxer number 1: B
Provide the Weight for boxer number 1: 56

DNI for boxer number 0, is: 123
Category for boxer number 0, is: A
Weight for boxer number 0, is: 45
DNI for boxer number 1, is: 789
Category for boxer number 1, is: B
Weight for boxer number 1, is: 56


DNI for boxer number 0, is: 123
Category for boxer number 0, is: A
Weight for boxer number 0, is: 45
DNI for boxer number 1, is: 7471203
Category for boxer number 1, is: x
Weight for boxer number 1, is: 7536756

【问题讨论】:

    标签: c function pointers struct


    【解决方案1】:

    &amp;xbox[i]-&gt;dni 是错误的。来自malloc 的返回值被分配给*xbox,所以*xbox 指向内存,xbox 指向那个指针。

    所以内存在*xbox。第一个结构是**xbox 或等价的(*xbox)[0]。下一个结构是(*xbox)[1],以此类推。因此,对于索引为i 的结构,您需要(*xbox)[i]。然后,因为这是一个结构,而不是指向它的指针,所以你需要.dni,而不是-&gt;dni。所以那个成员是(*xbox)[i].dni。那么它的地址就是&amp;(*xbox)[i].dni

    相反,由于xbox 是一个指向指针的指针,那么xbox[0] 就是那个指针,xbox[1] 就是那个指针。但是在那之后没有指针; xbox 只指向一个指针。所以xbox[i] 是错误的。

    例程中的其他成员引用也需要进行相同的更改。

    为了避免这个容易犯的错误,在传递指向指针的例程中,可以定义一个本地指针以使引用更容易:

    void loadData(boxers **xbox, int *xcount)
    {
        …
        boxers *p = *xbox = malloc(xcount * sizeof *p);
        …
            scanf("%d", &p[i]->dni);
        …
    }
    

    【讨论】:

    • 非常感谢您的回答。你和弗拉德的都指出了原始代码的正确问题。很清楚,现在我明白我对指针指针的解释出了什么问题。
    【解决方案2】:

    这些作业

    for (int i = 0; i < (*xcount); i++)
    {
        printf("Provide the DNI for boxer number %d: ", i);
        scanf("%d", &xbox[i]->dni);
        printf("Provide the Category for boxer number %d: ", i);
        scanf(" %c", &xbox[i]->cat);
        printf("Provide the Weight for boxer number %d: ", i);
        scanf("%d", &xbox[i]->weight);
    }
    

    不正确。你必须写

    for (int i = 0; i < (*xcount); i++)
    {
        printf("Provide the DNI for boxer number %d: ", i);
        scanf("%d", &( *xbox )[i].dni);
        printf("Provide the Category for boxer number %d: ", i);
        scanf(" %c", &( *xbox )[i].cat);
        printf("Provide the Weight for boxer number %d: ", i);
        scanf("%d", &( *xbox )[i].weight);
    }
    

    然后

    for (int i = 0; i < *xcount; i++)
    {
        printf("DNI for boxer number %d, is: %d \n", i, ( *xbox )[i].dni);
        printf("Category for boxer number %d, is: %c \n", i, ( *xbox )[i].cat);
        printf("Weight for boxer number %d, is: %d \n", i, ( *xbox )[i].weight);
    }
    

    比较上面的循环和main中的这个循环

    for (int i = 0; i < count; i++)
    {
        printf("DNI for boxer number %d, is: %d \n", i, box[i].dni);
        printf("Category for boxer number %d, is: %c \n", i, box[i].cat);
        printf("Weight for boxer number %d, is: %d \n", i, box[i].weight);
    }
    

    不同之处在于,在 main 中,指针 box 的类型为 boxers *,而在函数中,指针 xbox 的类型为 boxers **。因此,您首先需要取消引用函数中的指针,例如 ( *xbox ),然后像在 main 中一样应用下标运算符,例如 ( *xbox )[i].weight

    【讨论】:

    • 非常感谢您的回答。您和 Eric 都指出了原始代码的正确问题。很清楚,现在我明白我对指针指针的解释出了什么问题。
    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 2015-08-25
    • 1970-01-01
    • 2010-12-21
    • 2017-02-24
    • 1970-01-01
    • 2017-06-03
    相关资源
    最近更新 更多