-1

I am trying to use malloc to first allocate some space for an array, and then realloc to extend the array. The program compiles but I get some strange memory-print in the terminal when I run the program. The terminal says someting like: ======== Memory map ========= and then a bunch of numbers and stuff.

In my program, I use malloc as this:

struct station *addStation(struct station *graph, struct station newStation){
    graph = realloc(graph, sizeof(graph)+sizeof(struct station));
// Count the rows of graph[] here and add newStation to the end.
}

int main(){
    struct station *graph;
    graph = malloc(145*sizeof(struct station));
    graph = loadStations();
    newStation = graph[27];

    graph = addStation(graph, newStation);
}

Am I using it wrong?

Joran Den Houting
  • 3,149
  • 3
  • 21
  • 51
rablentain
  • 6,641
  • 13
  • 50
  • 91

6 Answers6

4

You are overwriting the pointer where your memory is:

graph = malloc(145*sizeof(struct station));
graph = loadStations(); // malloc'd memory is lost here

If you wish to add some data to the memory, you need to pass it as a pointer instead:

loadStations(graph);

Also, your sizeof(graph)+sizeof(struct station) only reserves data to 1 pointer and 1 station, which is not what you want. You need to pass the existing size information:

struct station * addStation(struct station * graph, size_t * count, struct station newStation){
    size_t newCount = *count + 1;
    graph = realloc(graph, newCount * sizeof(struct station));
    if(!graph)
        return 0;
    *count = newCount;
    // Copy new station here
    return graph;
}

and call in the main:

    temp = addStation(graph, &graphCount, newStation);
    if(temp)
        graph = temp;
user694733
  • 15,208
  • 2
  • 42
  • 68
3

sizeof(graph) returns the size of the graph pointer which is, for example, 4 bytes. It does not return the previously allocated size.

user1969104
  • 2,340
  • 14
  • 15
1

Yes. You don't mean sizeof(graph) in your addStation() function - that will be the size of graph, which is a struct station *, a regular pointer (and most likely 4 or 8 bytes).

You'll need a separate variable to keep count of the number of stations in your graph and then realloc() to the appropriate size every time.

Philip Kendall
  • 4,304
  • 1
  • 23
  • 42
  • 1
    +1 he could also use a struct with a counter and flexible array member. Either way, he needs to keep it *somewhere*. – WhozCraig Sep 26 '13 at 08:08
1

You need to fix a few things.

  • Check if malloc was successful.

    graph = malloc(145*sizeof(struct station));
    if(graph == NULL) {
        // your failure code here
    }
    
  • Do NOT overwrite the pointer to your allocated memory.

    graph = loadStations();   // Strict NO, this will cause a leak.
    

    instead pass the pointer in case you want to modify the data.

    loadStations(graph);
    
  • Its easier to keep the count of your stations and pass is to addStation

    struct station *addStation(struct station *graph, struct station newStation, size_t *count) {
        graph = realloc(graph, (*count + 1) * sizeof(struct station));
        if(graph == NULL) {
            // your failure code here
        }
    
        ++(*count);
    
        // your code here
    

    }

  • Free the allocated memory after use.

    free(graph);
    
HAL
  • 3,888
  • 3
  • 19
  • 28
0

This looks wrong you initialize graph with malloc then you erase it with function return.

graph = malloc(145*sizeof(struct station));
graph = loadStations();

This is bad too because it will returt sizeof(pointer)+sizeof(structure) so 4+struct size

sizeof(graph)+sizeof(struct station)

You can't retrieve the size allocated by previous malloc using sizeof. you need to store it someplace or to store number of elements.

ColdCat
  • 1,192
  • 17
  • 29
0

Here are my comments, this looks erroneous.

You have a pointer to graph by doing a malloc. Now you have overwritten this pointer value by the following line.

graph = loadStations();

/** Please see my comments inline **/

struct station *addStation(struct station *graph, struct station newStation){
    graph = realloc(graph, sizeof(graph)+sizeof(struct station));
// Count the rows of graph[] here and add newStation to the end.
}

int main(){
    struct station *graph;
    graph = malloc(145*sizeof(struct station));

    /** graph is a pointer, why are u manipulating the graph pointer to some other value **/
    /** The following line is bad **/
    graph = loadStations();



    newStation = graph[27];

    /** This is right **/
    graph = addStation(graph, newStation);
}
dexterous
  • 6,422
  • 12
  • 51
  • 99
  • Please [don't cast the result of `malloc()` in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Philip Kendall Sep 26 '13 at 08:26