user3050910
user3050910

Reputation: 3207

C: malloc, structure error

I do not know what is wrong with my code.

It seems to be something related to memory access but I don't find what or why. I would appreciate some help.

Code:

#include <stdio.h>
#include <time.h>
#include "ist.h"


#define LOGMESSAGE "Error. Try again: "

typedef struct {

  usint size;
  double *value;

} Vector;

void showVector(Vector vector);

/*  generateVector(int, int) -> double*/
Vector generateVector( int max, int size ) {

    usint i;
    Vector vector;

    if(size == 0) {
        fprintf( stdout, "1 element added to array\n" );
        vector.size = 1;
    }

    vector.value = malloc( ((size) * sizeof (double)) + 1);

    for(i = 0; i < size; i++) {
        vector.value[i] = ( (double)rand() * max / (double)RAND_MAX );
    printf("\n%f\n", vector.value[i]);
    }
    vector.value[size] = '\0';

    fprintf( stdout, "\nVector generated\n" );

    showVector(vector);
    return vector;
}

/*  save(double *) -> void*/
unsigned int save(Vector vector) {

    sint i;

    FILE *f_data = fopen("savedata.txt", "wt");

    if(f_data == NULL) {
        fprintf( stdout, "can't open file" );
        return 1;
    }

    for(i = 0; i < vector.size; i++)
        fprintf( f_data, "%.3f\n", vector.value[i] );

    fclose( f_data );

    return 0;
}

/*  showvector(double) -> void*/
void showVector(Vector vector) {

    usint i;

    line( 2, 0 );
    for(i = 0; i < vector.size; i++)
        fprintf( stdout, "[%2.d] %.3lf%c", i, vector.value[i],
                                  (i % 5) ? '\t' : '\n' );

    line( 2, 0 );
}

/*  sort(double*) -> double*/
Vector sort(Vector vector) {

    sint i;
    int change = true;

    while(change == true) {
      change = false;
      for(i = 0; i < vector.size; i++)
        if(vector.value[i + 1] > vector.value[i]) {
            double temp = vector.value[i];
        vector.value[i] = vector.value[i + 1];
        vector.value[i + 1] = temp;
        change = true;
        }
    }

    showVector( vector );

    return vector;
}

/*  interface(void) -> int*/
int interface(char **argv) {

    Vector vector;


    clear();
    fseek( stdin, 0, SEEK_END );

    vector = (argv == NULL) ? generateVector( i_dialog( "Max val:   ", LOGMESSAGE ),
                          i_dialog( "Vector size: ", LOGMESSAGE ) )
                            : generateVector( atoi( argv[1] ), atoi( argv[2] ) );

    showVector( vector );
    save( sort(vector) );
    free( vector.value );

    fprintf( stdout, "Press <ENTER>..." );
    CLEARBUFF();


    line( 2, 1 );
    menu( 2, "Repeat", "Exit" );

    return i_dialog( "\nchoice: ", LOGMESSAGE ) ? true : false;
}

int main(int argc, char **argv) {

    srand( (unsigned)time(NULL) );

    if(argc != 3)
      argv = NULL;

    while(interface( argv ));

    return 0;
}

Output (error):

Vector Size:  4
Max value:    5

0.659987

2.609337

2.122152

1.464432

s1e2: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted (core dumped)

Thank you very much

Upvotes: 0

Views: 145

Answers (2)

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

should be:

vector.value = malloc(size * sizeof(double) + sizeof(int));

and:

*((int *)(&vector.value[size])) = 0;

Upvotes: 0

Ed Swangren
Ed Swangren

Reputation: 124642

vector.value = malloc( ((size) * sizeof (double)) + 1);

That allocates enough space for size doubles plus one byte.

vector.value[size] = '\0';

This is a problem. Because value is of the type double*, dereferencing it results in getting or setting a double value. You use a character literal, which is of the type int. It is implicitly converted to a double, you write past the end of your allocated memory, and the result is undefined behavior.

Perhaps you meant to write the following because you also index past the end of your array in your sort function.

vector.value = malloc((size + 1) * sizeof(double));

Upvotes: 2

Related Questions