I'm using a custom vector in a Pebble app.
Pebble is crashing on the call to realloc
.
main.c
#include <pebble.h>
#include "movement.h"
static PointArray point_array;
int main(void) {;
point_array_create(&point_array, 1);
GPoint point1 = (GPoint){.x = 1, .y = 1};
GPoint point2 = (GPoint){.x = 2, .y = 2};
GPoint point3 = (GPoint){.x = 3, .y = 3};
point_array_push(&point_array, point1);
point_array_push(&point_array, point2);
point_array_push(&point_array, point3);
APP_LOG(APP_LOG_LEVEL_DEBUG, "Done\n");
}
movement.c
#include "movement.h"
#include "pebble.h"
static void point_array_resize(PointArray *point_array){
point_array->capacity *= 2;
size_t new_size = point_array->capacity * sizeof(GPoint) + sizeof(GPoint);
point_array->points = (GPoint*)realloc(point_array->points, new_size);
}
void point_array_create(PointArray *arr, int capacity) {
arr->points = (GPoint*)malloc(capacity * sizeof(GPoint));
arr->length = 0;
arr->capacity = capacity;
}
void point_array_push(PointArray *point_array, GPoint point) {
APP_LOG(APP_LOG_LEVEL_DEBUG, "pushing");
if (point_array->length > point_array->capacity) {
APP_LOG(APP_LOG_LEVEL_DEBUG, "resizing");
point_array_resize(point_array);
APP_LOG(APP_LOG_LEVEL_DEBUG, "successful resize");
}
point_array->points[point_array->length] = point;
point_array->length++;
APP_LOG(APP_LOG_LEVEL_DEBUG, "+ length");
}
movement.h
#include <pebble.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
GPoint *points;
int length;
int capacity;
} PointArray;
void point_array_create(PointArray *arr, int capacity);
void point_array_push(PointArray *point_array, GPoint point);
void point_array_destroy(PointArray *point_array, GPoint point);
GPoint move(GPoint point, float distance, float degrees);
The logs show that the app is crashing at the call to realloc
:
[DEBUG] movement.c:20: pushing
[DEBUG] movement.c:29: + length
[DEBUG] movement.c:20: pushing
[DEBUG] movement.c:29: + length
[DEBUG] movement.c:20: pushing
[DEBUG] movement.c:23: resizing
Here's what I tried:
point_array
and point_array->points
are not null andnew_size
is larger than the existing size of point_array->points
.realloc
at the bottom of point_array_create
, and it works fine. It just doesn't work in point_array_resize
.In point_array_push
, you test if you need to resize your points at the top, but the test is wrong. You only resize if the length has exceeded capacity, which means you have already overrun your array.
Instead, check to see if the length has reached capacity.
if (point_array->length == point_array->capacity) {
APP_LOG(APP_LOG_LEVEL_DEBUG, "resizing");
point_array_resize(point_array);
APP_LOG(APP_LOG_LEVEL_DEBUG, "successful resize");
}