1

I am planning to make a Linear Regression model using C. It takes a set of m points as input from stdin using scanf. The points are defined as a struct:

typedef struct{
    double x;
    double y;
} point_t;

The input is of format "%lf %lf". It then goes through all the points and carries out gradient descent, and outputs the parameters. I created a read_points() function for this purpose and it seems to be a little malfunctional. It works most of the time, but sometimes it gives off this error:

@MacBook-Pro Linear Regression % ./main < input.txt
main(13510,0x1e2685ec0) malloc: Incorrect checksum for freed object 0x14fe05d38: probably modified after being freed.
Corrupt value: 0x4035f851eb851eb8
main(13510,0x1e2685ec0) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort      ./main < input.txt

I am super rusty with dynamic memory allocation so I would really appreciate it if someone could help me spot the error in the code below. Is it because the computer is not able to allocate memory, or has it not been correctly freed? Thank you for your help!

point_t* read_points(int* count){
    int cap = 10;
    int i = 0; 
    point_t* arr = malloc(cap*sizeof(point_t));
    if (!arr){
        fprintf(stderr, "malloc() failed!\n");
        exit(1);
    }
    while(scanf("%lf %lf", &arr[i].x, &arr[i].y)==2){
        if (i>= cap){
            cap *=2;
            point_t* temp = realloc(arr,cap*sizeof(point_t));
            if(!temp){
                fprintf(stderr, "realloc() failed!\n");
                free(arr);
                exit(1);
            }
            arr = temp;
        }
        i++;
    }
    *count = i;
    return arr;
}
3
  • You need to check for i >= cap before reading data into arr[i]. Commented Jul 3 at 12:22
  • The problem is more obvious if you imagine starting with a capacity of zero. Commented Jul 3 at 12:24
  • Side note: Unlike some other StackExchange sites, StackOverflow does not support MathJax. Commented Jul 3 at 19:34

1 Answer 1

3

You have an off-by-one error:

while(scanf("%lf %lf", &arr[i].x, &arr[i].y)==2){
    if (i>= cap){
        ...
    }
    i++;
}

You don't increase cap until after reading into element arr[cap]. This results in writing past the end of allocated memory, triggering undefined behavior.

Increase i before checking cap:

while(scanf("%lf %lf", &arr[i].x, &arr[i].y)==2){
    i++;
    if (i == cap){
        ...
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Alt. for (; i < cap && scanf("%lf %lf", &arr[i].x, &arr[i].y)==2, ++i)
Awesome! Thank you to everyone that helped! I will also try using the condensed version!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.