Search code examples
cmallocfreerealloc

Function works ramdonly, overwriting memory, double free, corruption (!prev)


I learning C programing and I think I do well but this I have been trying for hours and I don't get what I'm doing wrong. I made a funtion to print an array and it works fine but just the first time, later on print weird character o don't work, with the gdb see that works fine but when I call printArray a second time the funtion integerToString dosen't works the second time. Honestly I don't know how to fix it, I asking for a few help please ;-; I'm asking anything you comment

The folowing code is a minimum reproducible example but the problem I think is just in the seeArray function and integerToString function

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

//Dependecy
int randomInRange(int lower, int upper){
    return (random() % (upper - lower + 1)) + lower;
}

//Dependecy
int countDigits(int num, int * numSize){
    *numSize = 0;
    do{
            (* numSize)++;
            num /= 10;
    }while(num != 0);

    return 0;
}

//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int integerToString(int num, char** strNum, int* strNumSize){
    countDigits(num, strNumSize);
    *strNum = (char *) malloc(sizeof(char) * (*strNumSize));
    if(*strNum == 0x0){
            fprintf(stderr, "No enough memory for convert interger to string");
            exit(EXIT_FAILURE);
    }

    for(int i = (*strNumSize-1); i > -1; i--){
            *( (*strNum) + i ) = num%10 + '0';
            num /= 10;
    }
    return 0;
}
//Dependecy
int initArray(int** array, int size){
    if(size<1){
            fprintf(stderr, "The array\'s size most be minimun one");
            exit(EXIT_FAILURE);
    }
    *array = (int*) malloc(sizeof(int)*size);
    if(*array == NULL){
            fprintf(stderr, "Couldn\'t reserve memory for array");
            exit(EXIT_FAILURE);
    }
    for(int i = 0; i < size; i++) *((*array)+i) == 0;
    return 0;
}

//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int seeArray(int* array, int size, char** arrayPhotography, int* arrayPhotographySize){
    int dataSize = 0;
    char* data = 0x0;

    for(int i = 0; i < size; i++){
            integerToString(*(array+i), &data, &dataSize);

            *arrayPhotographySize += sizeof(char) * ( 2 + dataSize );
            if(*arrayPhotography == 0x0){
                    *arrayPhotography = (char *) malloc(*arrayPhotographySize);
            }else{
                    *arrayPhotography = (char *) realloc(*arrayPhotography,*arrayPhotographySize);
            }
            if(*arrayPhotography == 0x0){
                    fprintf(stderr,"Not enoug memory for array\'s photography");
                    exit(EXIT_FAILURE);
            }

            strcat(*arrayPhotography, "[");
            strcat(*arrayPhotography, data);
            strcat(*arrayPhotography, "]");

            free(data);
            data = 0x0;
    }

    free(data);
    return 0;
}
//Dependecy
int printArray(int* array, int size){
    int arrayPhotographySize = 0;
    char* arrayPhotography = 0x0;
    if(seeArray(array, size, &arrayPhotography, &arrayPhotographySize)){
            fprintf(stderr, "Fuction printArray");
            exit(EXIT_FAILURE);
    }
    printf("Array:%s\n", arrayPhotography);
    free(arrayPhotography);
    return 0;
}
//Here is where things gets broke!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int main(int argc, char * argv[]){
    srand(time(NULL));
    int arraySize = randomInRange(1, 15);
    int* array = 0x0;
    initArray(&array, arraySize);
    for (int i = 0; i < 10; i++){
        printArray(array, arraySize);
    }
    free(array);
}

This are an image of how works randomly (I think so)

enter image description here


Solution

    1. It appears that in your initArray function, in the final for loop you write == instead of = to zero-fill the array. On a side note, there exists a function calloc in the <stdlib.h> header which will automatically zero-fill a dynamically allocated array for you, which is handy for avoiding simple mistakes like this.
    2. In your integerToString function, you only malloc enough space to hold the number of digits in the string. This is error-prone code however because most string operations in C (including strcat) require strings to be terminated by a null character. Allocate space for one extra character and then ensure the final character is 0.