为接收结构的函数分配适当的内存

Allocating the proper memory for a function that recieves a structure

提问人:Michael 提问时间:1/28/2023 最后编辑:trincotMichael 更新时间:2/1/2023 访问量:87

问:

我正在尝试创建一个动态数据库,我可以在其中修改其大小。 这是我到目前为止编写的代码,我将产品字符指针分配给其中,并将价格分配给我所期望的是创建数据库,并让我继续创建具有新大小的新数据库,以替换旧数据库,但到目前为止,它只返回内存方向并停止程序。null-1

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


typedef struct _product_t {
    char *product;
    float price;
} product_t;


product_t *newDatabase(product_t *database, int *dbSize, int newSize) {
    free(database);
    product_t *newdatabase = (product_t*)malloc(sizeof(database)*newSize);
    newdatabase->product = (char*)malloc(sizeof(char)*20);
    newdatabase->product = NULL;
    newdatabase->price = -1;
    free(newdatabase->product);
    return newdatabase;
}
int main(void) {
    product_t *database = NULL;
    int dbSize = 0;
    char cmd;
    do{
        printf("Command?");
        scanf(" %c", &cmd);
        switch (cmd) {

        case 'q':
            printf("Bye!");
            break;
        case 'n':
            printf("Size? ");
            int newSize2 = 0;
            scanf("%d", newSize2);
            newDatabase(database, &dbSize, newSize2);
            break;
        default:
            printf("Unkown command '%c'\n",cmd);
            }
    }while(cmd != 'q');
    return 0;

}
c malloc 内存 堆排序

评论

0赞 pmacfarlane 1/28/2023
scanf("%d", newSize2);错了,应该是.你的编译器可能告诉了你,而你忽略了它。&newSize2
0赞 Barmar 1/28/2023
sizeof(database)应该是sizeof(*database)
0赞 Barmar 1/28/2023
您应该使用 而不是 ,这样您就不会丢失 中的所有旧数据。realloc()malloc()database
0赞 Barmar 1/28/2023
main()需要做的事database = newDatabase(database, &dbSize, newSize2)
0赞 Barmar 1/28/2023
for的参数是什么?你从不使用它。dbSizenewDatabase()

答:

2赞 Barmar 1/28/2023 #1

用于更改分配的大小。数组的大小应该使用 ,因为只是指针的大小,而不是结构的大小。realloc()sizeof(*database)sizeof(database)

初始化新的数组元素时,需要一个循环。 指向数组的开头,而不是添加的新元素。newdatabase

product_t *newDatabase(product_t *database, int *dbSize, int newSize) {
    // Free the old `product` pointers if we're shrinking
    for (int i = newSize; i < *dbSize; i++) {
        free(database[i].product);
    }
    product_t *newdatabase = realloc(database, sizeof(*database)*newSize);
    if (!newdatabase && newSize != 0) {
        printf("Unable to allocate memory\n");
        exit(1);
    }
    // initialize the new pointers if we're growing
    for (int i = *dbSize; i < newSize; i++) {
        newdatabase[i].product = malloc(sizeof(char)*20);
        newdatabase[i].price = -1;
    }
    *dbSize = newSize;
    return newdatabase;
}

您还需要修复要求提供大小的行:

            scanf("%d", newSize2);

除了读取字符串时,需要传递要写入的变量的地址,所以应该是:

            scanf("%d", &newSize2);

评论

0赞 pmacfarlane 1/28/2023
第二个函数参数不正确。
0赞 pmacfarlane 1/28/2023
可能想提到破碎的答案以获得更完整的答案。scanf("%d")
0赞 Michael 1/28/2023
scanf 函数出了什么问题
0赞 pmacfarlane 1/28/2023
@Michael看我在上面关于原始问题的评论。
0赞 Michael 1/28/2023
是的,我看到了你的评论,但扫描的要点(“%d”, newSize2);是它总是在变化。如果我要应用更改,那么在从指针中获取整数的函数中会出现错误。
0赞 Michael 1/28/2023 #2

最新的完全工作版本,非常感谢大家的帮助!

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


            typedef struct _product_t {
                char *product;
                float price;
            } product_t;


            product_t *newDatabase(product_t *database, int *dbSize, int newSize) {
                // Free the previous memory allocated for the database
                free(database);

                // Allocate new space for newSize products on the heap
                database = (product_t*) malloc(newSize * sizeof(product_t));

                // Initialize all products in the database with NULL and -1
                for (int i = 0; i < newSize; i++) {
                    database[i].product = NULL;
                    database[i].price = -1;
                }

                // Update the database size
                *dbSize = newSize;

                // Return the pointer to the new database
                return database;
            }
            int main(void) {
                product_t *database = NULL;
                int dbSize = 0;
                char cmd;
                do{
                    printf("Command?");
                    scanf(" %c", &cmd);
                    switch (cmd) {

                    case 'q':
                        printf("Bye!");

                        break;
                    case 'n':
                        printf("Size? ");
                        int newSize2 = 0;
                        scanf("%d", &newSize2);
                        if(newSize2 < 0) {
                            printf("Must be larger than 0");
                            break;
                        }
                        else{
                        database = newDatabase(database, &dbSize, newSize2);
                        break;
                        }
                    default:
                        printf("Unkown command '%c'\n",cmd);
                        }
                }while(cmd != 'q');
                return 0;

            }

通过大家的帮助找到了工作解决方案,谢谢

评论

0赞 Username Obfuscation 1/31/2023
为他人的恩惠解释你的答案。请不要只是转储一整页代码,并期望其他人深入研究它。