3

I'm trying to create an array to hold an int, then when another int is to be added increase it in size to hold another int.. and so on..

I know it's not an efficient use of realloc, but it's proof on concept more than anything else. Just to get it working would allow me to optimise it and be able to apply it to something useful. A working example. The problem comes when i call the print function and it just segfaults. Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef char String[100];

void begin(int *);
void add(int *, int);
void print(int *);

int tempcount=0;

int main(void)
{
    int *n=NULL;
    String menu;

    begin(n);

    while(true)
    {
        scanf("%9s", menu);

        if(!strcmp("a", menu)) //add
        {
            int i=0;
            scanf("%d", &i);
            add(n, i);
        }
        else if(!strcmp("p", menu)) //print
        {
            print(n);
        }
        else if(!strcmp("q", menu)) //quit
        {
            free(n);
            break;
        }

    }

    return 0;
}

void begin(int *n)
{
    n=malloc(sizeof(int));

    if(n==NULL)
    {
        printf("Error in malloc!");
        return;
    }

    n[0]=0;

    printf("Added %d \n", n[0]);
}

void add(int *n, int numToAdd)
{
    static int sizeCount=0;
    sizeCount++;
    tempcount=sizeCount;

    int *temp;

    temp=realloc(n, (sizeCount+1) * sizeof(int));

    if(temp==NULL)
    {
        printf("Error in realloc!");
        return;
    }

    n=temp;

    n[sizeCount]=numToAdd;

    printf("Added %d \n", n[sizeCount]);

}

void print(int *n)
{
    int i;
    for(i=0; i<tempcount; i++)
    {
        printf("%d ", n[i]);
    }
}
Draconian Times
  • 319
  • 1
  • 3
  • 12
  • Why do you think `realloc` returns a pointer? – n. m. could be an AI Nov 02 '12 at 19:25
  • 8
    because it does? – hexist Nov 02 '12 at 19:27
  • This is related and thus of interest: http://stackoverflow.com/q/13098037/856199 – Nikos C. Nov 02 '12 at 19:28
  • @n.m. because its signature is `void *(*)(void *, size_t);` perhaps? –  Nov 02 '12 at 19:28
  • @H2CO3: very smart. why this signature and not any other? – n. m. could be an AI Nov 02 '12 at 19:29
  • @n.m. I don't get this. This signature is the signature of `realloc()`, because that's how it's defined in the standard library. –  Nov 02 '12 at 19:30
  • @hexist: `realloc` is an artefact engineered for a particular purpose, not a random natural phenomenon. Its signature is a direct consequence of its purpose. – n. m. could be an AI Nov 02 '12 at 19:32
  • 2
    @n.m.: `realloc` returns a pointer because it can't guarantee the "resized" block of memory will be in the same spot as the old. If it has to move the block, it needs some way to tell you where the new block is. – cHao Nov 02 '12 at 19:32
  • @H2CO3: yes, but why is it defined this way? – n. m. could be an AI Nov 02 '12 at 19:32
  • @n.m. nevermind :) cHao just answered that. –  Nov 02 '12 at 19:33
  • @n.m. not sure what you're trying to say. `realloc` is well defined to take a pointer to `NULL` or an existing `malloc`'ed block, a new size, and return a pointer to either the same pointer if it could do the resize in place, or the new pointer you should use if it had to move your data. It's pretty well defined.. ya know, by international standards and such (ISO 9899) – hexist Nov 02 '12 at 19:35
  • @cHao: I appreciate your and everybody else's knowledge but the question was intended for the original poster. It was an attempt to guide him to an answer he could figure out mostly himself, instead of providing a ready-made one. It's too late anyway. – n. m. could be an AI Nov 02 '12 at 19:36
  • @n.m.: You might want to be more up-front about that kind of thing in the future. :) Now that i look at your questions with that info, it's semi obvious where you were going with it...but before you clarified the intent, it looked like you were just totally mystified by `realloc`. – cHao Nov 02 '12 at 19:41
  • @cHao: ok, in the future I will state in big bold letters that the question is a pedagogical device ;) – n. m. could be an AI Nov 02 '12 at 19:46
  • 3
    @n.m. Next time ask "What do you think is the reason..." to prevent misunderstandings. – Daniel Fischer Nov 02 '12 at 19:46

2 Answers2

8

You need to pass a pointer to your pointers in add/begin so they can modify your pointer in main

begin(&n);
...
add(&n, i);

and your definition

void begin(int **n)
{
    *n=malloc(sizeof(int));

    if(*n==NULL)
    {
        printf("Error in malloc!");
        return;
    }

    (*n)[0]=0;

    printf("Added %d \n", (*n)[0]);
}

and

void add(int **n, int numToAdd)
{
    static int sizeCount=0;
    sizeCount++;
    tempcount=sizeCount;

    int *temp;

    temp=realloc(*n, (sizeCount+1) * sizeof(int));

    if(temp==NULL)
    {
        printf("Error in realloc!");
        return;
    }

    *n=temp;

    (*n)[sizeCount]=numToAdd;

    printf("Added %d \n", (*n)[sizeCount]);

}

Right now what you're doing is modifying local copies of your pointer in begin/add, so when you change it in those functions it's not modifying your pointer n in main

Also, fun fact, if you pass NULL as the first parameter to realloc it acts like a malloc, so if you initialize n to NULL, you can simply call add without first doing a begin.

hexist
  • 5,151
  • 26
  • 33
0

Check your function add - are you sure you update the pointer value? Try with ** as a parameter - I think it will help.

Nik
  • 1
  • 4