0

I'm having a problem when using realloc() in one function and with the same algorithm, it doesn't work for the other. I can't understand where I'm making a mistake.

For the initVertex function this algorithm works fine. But in the initFace every time I try to allocate memory for the faces it says:

realloc(): invalid next size.

The files I'm reading from is in .obj format:

for vertex: v -0.187264 0.10108 0.266814

for face: f 938/938/936 944/944/942 936/936/934

Here is the code:

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

#include "Scene.h"

#define MAX_ID 10
#define LIMIT 10
#define MEM_INCREASE 10


void setArrToZero(char *arr) {
    for (int i = 0; i < LIMIT; ++i) {
        *(arr + i) = 0;
    }
}

void initFace(Object *obj, char *line, int length, int *maxFaces) {
    int i = 0, strCounter = 0;
    (obj->faces)[obj->numberOfFaces].size = 0;
    (obj->faces)[obj->numberOfFaces].vertex = (int*) malloc(MAX_ID * sizeof(int));
    char *numStr = (char*) malloc(length * sizeof(char));
    enum boolean flag = FALSE;
    if (obj->numberOfFaces == *maxFaces) {
        obj->faces = (Face*) realloc(obj->faces,
                (*maxFaces + MEM_INCREASE) * sizeof(Face));
        *maxFaces += 10;
    }
    while (i != length) {
        char c = line[i];
        if (c == ' ' && flag == FALSE)    //turn the flag on
            flag = TRUE;
        if (c == '/' && flag == TRUE) { //turn the flag off and initialize Face.
            flag = FALSE;
            (obj->faces)[obj->numberOfFaces].vertex[obj->faces->size] = atoi(
                    numStr);
            (obj->faces)[obj->numberOfFaces].size++; // increase number of vertexes of the face.
            setArrToZero(numStr);
            strCounter = 0;
        }
        if (flag == TRUE) {
            numStr[strCounter] = c;
            strCounter++;
        }
        if ((obj->faces)[obj->numberOfFaces].size == MAX_ID) {
            break;
        }

        i++;
    }
    obj->numberOfFaces++;
    free(numStr);
}

void initVertex(Object *obj, char *line, int *maxVertexes) {
    float x, y, z;
    if (line[1] != ' ')
        return;
    else {
        if (obj->numberOfVertexes == *maxVertexes) {
            obj->vertexes = (Vertex*) realloc(obj->vertexes,
                    sizeof(Vertex) * (*maxVertexes + MEM_INCREASE));
            *maxVertexes += 10;
        }
        sscanf(line, "%*[^-0123456789]%f%*[^-0123456789]%f%*[^-0123456789]%f",
                &x, &y, &z);
        (obj->vertexes)[obj->numberOfVertexes].x = x;
        (obj->vertexes)[obj->numberOfVertexes].y = y;
        (obj->vertexes)[obj->numberOfVertexes].z = z;
        obj->numberOfVertexes++;
    }
}

Object* createObject(char *fileName) {
    Object *obj = (Object*) malloc(sizeof(Object));
    int maxVertexes = 10, maxFaces = 10;
    obj->numberOfFaces = 0;
    obj->numberOfVertexes = 0;
    obj->vertexes = (Vertex*) malloc(maxVertexes * sizeof(Vertex));
    obj->faces = (Face*) malloc(maxFaces * sizeof(Face));
    FILE *inputF;
    size_t len = 0;
    char *line = NULL;
    inputF = fopen(fileName, "r");
    if (inputF == NULL) {
        printf("File not exist!");
        return NULL;
    }
    while (!feof(inputF)) {
        getline(&line, &len, inputF);
        char c = line[0];
        switch (c) {
        case 'v':
            initVertex(obj, line, &maxVertexes);
            break;
        case 'f':
            initFace(obj, line, len, &maxFaces);
            break;
        default:
            break;
        }
    }
    return obj;
}

int main() {


    Object *obj = createObject("Donald.obj");
    printf("done");

}
alk
  • 69,737
  • 10
  • 105
  • 255
  • Does this answer your question? [Facing an error "\*\*\* glibc detected \*\*\* free(): invalid next size (fast)"](https://stackoverflow.com/questions/2317021/facing-an-error-glibc-detected-free-invalid-next-size-fast) – Shloim Jan 05 '20 at 10:18
  • Use valgrind to debug your code, you probably have some buffer overrun. See linked question. – Shloim Jan 05 '20 at 10:19
  • 2
    Probably not related to your problem, but the `while (!feof(inputF))` doesn't sound correct to me. See [Why is while ( !feof (file) ) always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Lxer Lx Jan 05 '20 at 11:01
  • `fopen` can fail for many reasons even when the file does exist. Printing the string "File not exist!" when there is a permissions error will (not "may", but "will") cause unnecessary confusion and time lost. Print a reasonable error message. `if(inputF == NULL) { perror(fileName); return NULL; }` – William Pursell Jan 05 '20 at 12:05

1 Answers1

2

initVertex() reallocates the array vertexes before it uses the out-of-bound index numberOfVertexes.

initFace() uses the out-of-bound index numberOfFaces twice here:

    (obj->faces)[obj->numberOfFaces].size = 0;
    (obj->faces)[obj->numberOfFaces].vertex = (int*) malloc(MAX_ID * sizeof(int));

and only after having done reallocates the array faces.

Accessing the array faces out of bound provokes undefined behaviour. Anything can happen from then one. In this particular case the program's memory management seems to have been messed up.

alk
  • 69,737
  • 10
  • 105
  • 255