-1

Possible Duplicate:
Using Dynamic Memory allocation for arrays

I originally had this program store prices with a quantity size of ten and realized that I wanted to make the program more dynamic because I may need to store more than ten items at some given point. I'm having difficulties understanding on how to reallocate additional memory so that I can store any amount of items I would need. Is this the correct way of handling this task?

main function:

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

outside function

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;
}
0

4 Answers 4

1

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

What is more:

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

You tried to allocate the i*sizeof(int) and then casted it to double*. When double and int have different sizes your code would have a difficult to find bug.

The next thing:

When i is equal to 0 you allocate memory with initial size 0 bytes (i*sizeof(int)) and then try to use it. It won't work. Try to change your loop in this way: for (int i = 1, i <= QUANTITY_SIZE;... and keep purchases[i-1].

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for pointing that out, I've just corrected that. Thanks for the explanation as well.
Look also at Daniel's answer. His notice is very important as well. Remember to +1 him ;)
So remove purchases[i-1] with purchase[i]?
I had that originally, I just wasn't sure why I kept seeing that in most of the examples that were demonstrating the setup for reallocating memory. I'm running the program and it's giving me a run-time error saying "Thread 1: EXC_BAD_ACCESS(code=1, address=0x1)" and it's highlighting where my for loop starts. What could this mean?
1

This is wrong:

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

First, you overwrite the just realloced pointer, you meant to have

purchases = storeMoreItems;

there instead of the other way round. But that would not influence the value the passed-in purchases pointer has in the calling function.

For that, you'd need to pass the address of purchases from main to

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

and assign

*purchases_ptr = storeMoreItems;

The reallocation itself,

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

uses the wrong type for the calculation of the size to allocate, that is almost certainly very wrong too.


In main:

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

and startShopping would look something like

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;
}

3 Comments

I really appreciate the feedback, especially with on addressing purchases back into the main function. I figured I would need a two-dimensional pointer, would you mind on how that works?
I'm not entirely sure I understand what you're trying to do correctly, but I'll give it a shot. Will take a few minutes.
Not a problem, no hurry. I'm trying to add as many item prices into the array as needed by the user, instead of limiting it to 10 items.
0

The first thing you want to do is make sure you're allocating the right number of bytes. Malloc doesn't know that you want to use the memory for doubles so you need to multiply by sizeof(double):

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

Comments

0

Check out realloc.

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

Reallocate memory block Changes the size of the memory block pointed to by ptr.

Get more details from here http://www.cplusplus.com/reference/cstdlib/realloc/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.