-3

I use this code, with this structure, im trying to make function to add item into array of this structure

typedef struct goods{
    char *name;
    int num;
} goods;

void addWord(char *what, goods *where, int pnr, int *arrsize, int n){               
    if (pnr >= *arrsize){
        where = (goods*)realloc(where,*arrsize*2*sizeof(goods*));
        *arrsize*=2;
    }
    where[pnr].name = (char*)malloc(strlen(what)*sizeof(char));
    strcpy(where[pnr].name,what);
    where[pnr].num = n;
}

in main function i have this:

int extstore = 1;
goods *store = (goods*)malloc(1*sizeof(goods*)); 

    addWord(line, store, nr, &extstore, n);

Why am I getting an "invalid next size" runtime-error on the line where = (goods*)realloc(where,*arrsize*2*sizeof(goods*)); in addWord()?

EDIT:

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

typedef struct goods{
    char *name;
    int r;
} goods;

int main()
{
    int  linelen, i, nr = 0, current_r;
    char *line = NULL;
    size_t len = 0;
    int extstore = 1;
    goods *store;
    store = malloc(extstore*sizeof(goods*));

    while (1){
        while ((linelen = getline(&line, &len, stdin)) != -1){
            if (line[linelen - 1] == '\n'){
                line[linelen - 1] = '\0';
            }

            linelen = strlen(line);

            if (line[0] == '#'){
                if (sscanf(line,"#%d",&current_r) != 1){
                    printf("bad input.");
                    return 0;
                } else continue;
            }

            if (nr >= extstore){
                store = realloc(store,extstore * sizeof(goods*) * 2);
                extstore*=2;
            }

            store[nr].name = malloc(strlen(line)*sizeof(char));
            strcpy(store[nr].name,line);
            store[nr].r = current_r;

            nr++;
        }
        if (linelen == -1) break;
    }

    printf("\n");
    for (i = 0;i < nr;i++){
        printf("%s, [id:%d]\n", store[i].name, store[i].r);
    }
    return 0;
}
lllook
  • 729
  • 2
  • 7
  • 20
  • 2
    You forgot to ask a question. – Mureinik Dec 06 '14 at 16:02
  • @Mureinik: He asked a question. It's "Why do I get that error in my code, on the indicated line?". Admittedly, not having an explicit question with a question-mark is a bad idea. At least he provides all the info to figure out what's wrong... – Deduplicator Dec 06 '14 at 16:10
  • what kind of error did you get? – 4pie0 Dec 06 '14 at 16:14

2 Answers2

1
extstore * sizeof(goods*) * 2

should be extstore * sizeof(goods) * 2 because the space for structures should be allocated - not just for pointers.

There is a fundamental problem in your code. You are passing pointer by value, which means that any change made to a pointer (not the variable pointed to, but the pointer itself) will not be visible from outside the function. You should pass a pointer by pointer instead, and you should check the result returned from realloc. Secondly, don't assign result of realloc back to same pointer - in case of failure you will lost pointer to memory -> thus, memory leak will occur.

To pass pointer by pointer:

void addWord( char *what, goods **where, size, ...) {
  if ( *where == NULL) return; // nothing to do
  if ( size < 1) return;       // it would result in realloc=free call 
  goods *res = NULL;
  res = realloc( *where, size * sizeof( goods));

  if ( res != NULL) {
     *where = res;
   }
   else {
     // Error (re)allocating memory
     // If realloc() fails the original block is left untouched,
     // it is not freed or moved, so here *where is unchanged
   }

And there is no need in C to cast a result from malloc.

* Error in `path': realloc(): invalid next size: 0x0000000000ec8010 *

This failure must be because "where" is invalid due to a heap corruption earlier in the execution.

4pie0
  • 29,204
  • 9
  • 82
  • 118
  • I dont understand, I change arrsize in addWord function, and it changes outside that function too. – lllook Dec 06 '14 at 16:28
  • in a line where = (goods*)realloc(where,*arrsize*2*sizeof(goods*)); you are assigning new value to "where", but "where" is passed by value -> therefore new value is assigned to copy of "where", and outside function "where" will point still to an old (and now incorrect) address – 4pie0 Dec 06 '14 at 16:40
  • i just removed the whole function and moved it into main(), i am getting same error – lllook Dec 06 '14 at 16:45
  • *** Error in `path': realloc(): invalid next size: 0x0000000000ec8010 *** – lllook Dec 06 '14 at 17:38
  • i removed addWord function and moved it straight into the main function where is declaration of "store", then there is while which is reading input until EOF, there is no more "where", i dont get it why i keep getting this error – lllook Dec 06 '14 at 18:49
  • I updated first post of mine, what im trying to do is to fill dynamic array of structure type goods, with items (name, ID), when i read line that starts with '#' i increase current_r, which i want to store in this array as ID corresponding with name of that item – lllook Dec 06 '14 at 18:56
0

C is pass-by-value.

Which means changing an argument in the function does not change the expression it was initialized from.

Thus, the first time realloc moves the memory, the pointer in main will be bad.

To correct that, either use an extra level of indirection, or preferably return the new value as the result.

(Anyway, you should check for allocation failure (malloc and realloc),
and you should not cast from void* to any pointer-type in C.)

Community
  • 1
  • 1
Deduplicator
  • 44,692
  • 7
  • 66
  • 118