数组的内存分配[重复]

Posted

技术标签:

【中文标题】数组的内存分配[重复]【英文标题】: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;

【问题讨论】:

【参考方案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));

【讨论】:

以上是关于数组的内存分配[重复]的主要内容,如果未能解决你的问题,请参考以下文章

与解除分配堆数组相关的语法混淆[重复]

在C中为结构中的单个字符分配内存[重复]

分配数组 VS。可变长度数组[重复]

java中创建数组时怎么分配内存?

C# 中锯齿状数组的内存分配与 C++ 中的二维数组内存分配

java分配内存空间