0

I am new to C and trying to have a dynamic array inside a struct, to which I need to add a dynamic number of items.

If I use malloc with a big number (like +100000) when initialising the container, the program works fine.

However, if I just allocate sizeof(struct ...) memory, and then try to reallocate using realloc, the program crashes when I try to add new item to the array. Even if I add +1000000 size when reallocating, it still crashes, while the same size works if I use it when allocating in the first place.

Cut down code to display my problem:

struct Station {
    char name[100];
};

struct StationContainer {
    int numberOfStations;
    struct Station *stations[];
};

struct StationContainer *makeContainer() {
    struct StationContainer *new;
    // If I add +1000000 in size here, the program works fine
    new = (struct StationContainer *) malloc(sizeof(struct StationContainer));

    if (new == NULL) {
        fprintf(stderr, "makeContainer: out of memory\n");
        exit(1);
    }

    new->numberOfStations = 0;

    return new;
}

int main(int argc, int argv[]) {

    // Initialize the container
    struct StationContainer *container;
    container = makeContainer();

    // Add new station to container
    struct Station *new;
    new = (struct Station *) malloc(sizeof(struct Station));

    if (new == NULL) {
        fprintf(stderr, "makeStation: out of memory\n");
        exit(1);
    }

    strcpy(new->name, name);

    // Add to the container
    // Even if I add +1000000 here, it still crashes below when I add new item
    container = (struct StationContainer *) realloc(container, sizeof(struct StationContainer) + 1000000);

    if (container == NULL) {
        fprintf(stderr, "makeStation: container out of memory\n");
        exit(1);
    }

    container->stations[container->numberOfStations] = new;
    container->numberOfStations++;


}

EDIT1: The problem in my cut down version was spotted, however, once I returned to full version, I was still getting the error. I got the container out of memory. That was because my container->numberOfStations was wildly big after first increment for some reason.

My full code at: codepad

The adjacencies.txt file contents:

Baker Street, Bond Street, Regent's Park
Bond Street, Marble Arch, Baker Street, Oxford Circus, Green Park
Marble Arch, Bond Street
Green Park, Bond Street, Oxford Circus, Piccadilly Circus
Regent's Park, Baker Street, Oxford Circus
Oxford Circus, Bond Street, Regent's Park, Warren Street, Tottenham Court Road, Piccadilly Circus
Piccadilly Circus, Green Park, Oxford Circus, Leicester Square, Charing Cross
Warren Street, Oxford Circus, Goodge Street
Goodge Street, Warren Street, Tottenham Court Road
Tottenham Court Road, Oxford Circus, Goodge Street, Holborn, Leicester Square
Leicester Square, Piccadilly Circus, Tottenham Court Road, Covent Garden, Charing Cross
Charing Cross, Piccadilly Circus, Leicester Square
Covent Garden, Leicester Square, Holborn
Holborn, Tottenham Court Road, Chancery Lane
Chancery Lane, Holborn

When I make the stations, if I leave container->numberOfStations unchanged, there is no problem. However, when I at least increment it once, combined with the realloc, it changes to huge numbers. Example output:

Number of stations: 0
!Station name:[Baker Street]
Number of stations: 1
!Station name:[Bond Street]
Number of stations: 4067560
makeStation: container out of memory

I feel like there is a small error somewhere that makes my numberOfStation change wildly even though it's supposed to increment just by one?

7
  • 1
    First note: don't cast malloc return value. Second note: calling a variable new is not recommended. Where is name declared ? strcpy(new->name, name); Commented Feb 15, 2017 at 16:49
  • Will change that, I was just following notes from my Uni lectures Commented Feb 15, 2017 at 16:49
  • Can you give some input and exact line where you are getting the error using gdb ? Commented Feb 15, 2017 at 16:52
  • sizeof(struct StationContainer) + 1000000 makes no sense in malloc()/realloc() as you want the amount of memory allocated to be multiple sizes of struct StationContainer - did you mean to write sizeof(struct StationContainer) * 1000000 Commented Feb 15, 2017 at 16:53
  • @ChrisTurner no, + 1000000 is just for debugging, showing that when I allocate memory in the first place it works, but when I try to reallocate it doesn't work. In the first place yes, it will be sizeof(struct(Station)) * numberOfStations Commented Feb 15, 2017 at 16:55

2 Answers 2

4

In the original version posted, container->numberOfStations was uninitialized.
In makeContainer you might consider using calloc() or memset() to initialize your container to zero - it works nicely when you add new items to the struct and they still should be initialized to zero.

In the current version I can spot no error, and neither can valgrind. I took the liberty of declaring a name within the constraints of the 100 char limit.

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

3 Comments

Good eyes. didn't notice you've answered. :) deleted mine.
Good spot, I accidentally deleted that when cut down the code for this preview. I will edit it now to show how it is.
I have made another edit showing exactly how I get my error. It happens when I try to increment my container->numberOfStations by one. I have added a link to full code a codepad.org as well. Thanks a lot for your help!
2

Well - look at

struct StationContainer {
    int numberOfStations;
    struct Station *stations[];
};

So stations is pointer

So makeContainer just gives it enough space for a pointer etc. You have not even allocated the memory for the pointer to have information nor initialised numberOfStations. It is just an uninitialised pointer

PS: Does this compile

   strcpy(new->name, name);

Cannot find the declaration for name

5 Comments

Yes he did allocate. He's pointing to new with that pointer.
Eh? name is not declared. new->name has memory
@Tony container->stations isn't defined though so you can't access any elements of it
I meant he allocated memory for StationContainer. For Station he indeed didn't. I've pointed it out in comments.
In my edited code the container->stations works fine, I can write and read at least 1 station from there. It's the container->numberOfStations that gets wildly big and therefore program runs out of memory.

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.