【问题标题】:Memory Allocation with Arrays [duplicate]数组的内存分配[重复]
【发布时间】:2012-12-13 03:51:39
【问题描述】:

可能重复:
Using Dynamic Memory allocation for arrays

我最初有这个程序存储价格,数量大小为 10,并意识到我想让程序更具动态性,因为我可能需要在某个给定点存储超过 10 个项目。我很难理解如何重新分配额外的内存,以便我可以存储我需要的任何数量的项目。这是处理此任务的正确方法吗?

主要功能

double *purchases = (double*)malloc(QUANTITY_SIZE);

外部函数

double startShopping(double *purchases, double *taxAmount, double *subTotal, double *totalPrice)
{
    double itemPrice = 0.00;
    double* storeMoreItems;

    for(int i = 0; i < QUANTITY_SIZE; *subTotal +=purchases[i++])
    {
        while(itemPrice != -1)
        {
            printf("Enter the price of the item :");
            scanf("%lf", &itemPrice); 

            storeMoreItems = (double*)realloc(storeMoreItems, i * sizeof(int));

            if(storeMoreItems != NULL)
            {
                storeMoreItems = purchases;
                purchases[i-1] = itemPrice;
            }

           else
           {
               free(purchases);
           }
       }
  }

  displayCart(purchases);

  *taxAmount = *subTotal * TAX_AMOUNT;

  *totalPrice = *taxAmount + *subTotal;

  printf("\nTotal comes to : $%.2lf\n", *totalPrice);

  return *totalPrice;
}

【问题讨论】:

    标签: c memory dynamic


    【解决方案1】:

    这是错误的:

            if(storeMoreItems != NULL)
            {
                storeMoreItems = purchases;
                purchases[i-1] = itemPrice;
            }
    

    首先,你覆盖刚才的 realloced 指针,你应该有

    purchases = storeMoreItems;
    

    在那里,而不是相反。但这不会影响传入的purchases指针在调用函数中的值。

    为此,您需要将purchases 的地址从main 传递到

    double startShopping(double **purchases_ptr, double *taxAmount, double *subTotal, double *totalPrice)
    

    并分配

    *purchases_ptr = storeMoreItems;
    

    重新分配本身,

    storeMoreItems = (double*)realloc(storeMoreItems, i * sizeof(int));
    

    使用错误的类型来计算要分配的大小,这几乎肯定也是非常错误的。


    main:

    size_t purchase_count = QUANTITY_SIZE;
    double *purchases = malloc(purchase_count * sizeof *purchases);
    // ...
    startShopping(&purchases, &purchase_count, taxAmount, subTotal, totalPrice);
    // ...
    

    startShopping 看起来像

    double startShopping(double **purchases_ptr, size_t *purchase_count,
                         double *taxAmount, double *subTotal, double *totalPrice)
    {
        double itemPrice = 0.00;
        double* purchases = *purchases_ptr;
        size_t i;
    
        for(i = 0; ; *subTotal += purchases[i++])
        {
            printf("Enter the price of the item :");
            scanf("%lf", &itemPrice);
    
            // I'm assuming you don't really want to add the -1
            // entered for termination
            if (itemPrice == -1) {
                break;
            }
    
            if (i == *purchase_count) {
                // array filled, let's get more space
                // double it, or add a fixed amount,
                // but rather not just one element each round
                *purchase_count *= 2;
    
                // we have the address saved in another variable, so here we can
                // store the pointer returned by realloc in purchases without losing
                // the handle if realloc fails
                purchases = realloc(purchases, *purchase_count * sizeof *purchases);
    
                if (purchases == NULL) {
                    // reallocation failed, now what?
    
                    // throw a tantrum?
                    free(*purchases_ptr);
                    exit(EXIT_FAILURE);
    
                    // or can something less drastic be done?
                } else {
                    // Okay, got the needed space, let's record the address
                    *purchases_ptr = purchases;
                }
            }
            purchases[i] = itemPrice;
        }
    
        // store the number of items actually read in?
        *purchases_count = i;
    
        // That should probably also get passed the number of items stored
        displayCart(purchases);
    
        *taxAmount = *subTotal * TAX_AMOUNT;
    
        *totalPrice = *taxAmount + *subTotal;
    
        printf("\nTotal comes to : $%.2lf\n", *totalPrice);
    
        return *totalPrice;
    }
    

    【讨论】:

    • 我非常感谢您的反馈,尤其是在将购买问题重新纳入主要功能时。我想我需要一个二维指针,你介意它是如何工作的吗?
    • 我不完全确定我是否理解您要正确执行的操作,但我会试一试。需要几分钟。
    • 没问题,不急。我正在尝试根据用户需要将尽可能多的商品价格添加到数组中,而不是将其限制为 10 件商品。
    【解决方案2】:

    double* purchases = (double*)malloc(sizeof(double)*QUANTITY_SIZE);

    还有什么:

    storeMoreItems = (double*)realloc(storeMoreItems, i * sizeof(double));

    您尝试分配i*sizeof(int),然后将其转换为double*。当doubleint 的大小不同时,您的代码将很难找到错误。

    接下来的事情:

    i 等于 0 时,您分配初始大小为 0 字节 (i*sizeof(int)) 的内存,然后尝试使用它。它行不通。尝试以这种方式更改循环:for (int i = 1, i &lt;= QUANTITY_SIZE;... 并保留purchases[i-1]

    【讨论】:

    • 感谢您指出这一点,我刚刚更正了这一点。也感谢您的解释。
    • 看看丹尼尔的回答。他的通知也很重要。记得给他 +1 ;)
    • 那么用 purchase[i] 删除购买[i-1]?
    • 我最初有这个,我只是不知道为什么在大多数演示重新分配内存的设置的示例中我一直看到这个。我正在运行程序,它给了我一个运行时错误,说“线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x1)”,它突出显示了我的 for 循环开始的位置。这意味着什么?
    【解决方案3】:

    查看 realloc。

    void * realloc ( void * ptr, size_t size );

    重新分配内存块改变ptr指向的内存块的大小。

    从这里获取更多详细信息http://www.cplusplus.com/reference/cstdlib/realloc/

    【讨论】:

      【解决方案4】:

      您要做的第一件事是确保分配正确的字节数。 Malloc 不知道你想将内存用于双精度所以你需要乘以sizeof(double)

      double *purchases = (double*)malloc(QUANTITY_SIZE * sizeof(double));
      

      【讨论】:

        猜你喜欢
        • 2012-03-24
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2016-10-08
        • 1970-01-01
        • 2012-10-09
        • 2018-09-06
        • 2018-09-29
        相关资源
        最近更新 更多