0

Assuming that I have a program that has an array of unknown lenght that consists of Customers.

Here, a customer struct:

struct Customer
{
 char* lastname;
 char* firstname;
 int money;
};

And here - an array:

Customer* CustomerDB;

Okay. But the thing is that I want to add and remove customers dynamically during runtime. I don't want to allocate like 100 customers during declaration or during runtime - I want to allocate one at a time when it is needed.

Think of a simple AddCustomer function that allocates memory, enters the given data and then increments a counter (which is probably needed for iteration).

This is my main problem.

What I want is the array to behave exactly like one that has been declared with 100 arrays instead of a dynamical one.

The customer program above is just an example, please don't tell me that it's a bad idea to do that and that or that.

  • How do I create an AddCustomer function working for the code above?

  • It is necessary that I can iterate through CustomerDB

4
  • 4
    So are you not allowed to use vector or string? Also in C++, we prefer the type-safe and correct new over malloc. Commented Feb 23, 2010 at 15:46
  • Can new be used on structs? Commented Feb 23, 2010 at 15:49
  • 1
    yes, new can be used on structs --- in C++ structs are basically the same as classes (some of the defaults are different, that's all). Commented Feb 23, 2010 at 15:53
  • 4
    Yes new can be used on structs. "struct" and "class" are identical except for the default visibility Commented Feb 23, 2010 at 15:53

6 Answers 6

6

Use standard template library std::vector or a vector of pointers.

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

Comments

3

Use a standard library container, such as vector, deque, or list.

Comments

2

I suppose the AddCustomer function might be implemented like this:

void AddCustomer(Customer** db, int current_count);

where the memory re-allocation might be done in terms of realloc.


However, you do realize that you are not taking advantage of anything that C++ offers, so you could have just posted this as a C question (in C++ this is a no-brainer with vector/deque/list and push_back)?

Comments

0

If you can use std::vector or similar, use that, they're purpose-built for this sort of problem. I'd also replace the raw char * with std::string at the same time.

If you're stuck with the approach above, you might want to change the size of the allocated array using realloc() when the size changes. However that's a very manual way of implementing what a combination of vector & string can do for you much easier and without potential resource leaks.

Comments

0

Here are just some thoughts

Judging from your requirements it sounds as if you would be better off with a list than an array. A list would fit more natural to your requirements regarding the dynamics and having no max limit.

Either you could create your own linked list using a pointer in each list element or use std::dequeue or similar however you would anyway need to take care of what the pointers inside your struct are pointing to. Simplest case in your example would probably to use std::string instead of pointers - then the strings are automatically copied and you don't have to concern yourself with the memory (or use boost::shared_array as pointers).

struct Customer
{
 string lastname;
 string firstname;
 int money;
};

Just my 2c

Comments

0

As you suggested, this is not the "Correct" way to do things - but heres what you asked for.

typedef struct _tag_Customer {
    char *LastName; 
    char *FirstName; 
    double Money; 
} CUSTOMER, *LPCUSTOMER;

typedef struct _tag_Customers {
    CUSTOMER *Collection;
    int Count;
} CUSTOMERS, *LPCUSTOMERS;

LPCUSTOMER AddCustomer(LPCUSTOMERS pCustomers, const char *sLastName, const char *sFirstName, double dMoney)
{
    int iRequiredMemory = (sizeof(CUSTOMER) * (pCustomers->Count + 1));
    if(!(pCustomers->Collection = (LPCUSTOMER) realloc(pCustomers->Collection, iRequiredMemory)))
    {
        return NULL; //Memory allocation error.
    }

    LPCUSTOMER pCutsomer = &pCustomers->Collection[pCustomers->Count];

    pCustomers->Count++;

    iRequiredMemory = strlen(sLastName) + 1;
    pCutsomer->LastName = (char *) calloc(iRequiredMemory, sizeof(char));
    strcpy(pCutsomer->LastName, sLastName);

    iRequiredMemory = strlen(sFirstName) + 1;
    pCutsomer->FirstName = (char *) calloc(iRequiredMemory, sizeof(char));
    strcpy(pCutsomer->FirstName, sLastName);

    pCutsomer->Money = dMoney;

    return pCutsomer;
}

void main(void)
{
    CUSTOMERS Database;
    memset(&Database, 0, sizeof(CUSTOMERS));

    AddCustomer(&Database, "Smith", "Joe", 100.99);
    AddCustomer(&Database, "Jackson", "Jane", 100.99);
    AddCustomer(&Database, "Doe", "John", 100.99);

    //You'll need to free the Memory, of course.
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.