2016-07-25 18 views
1

私はPebbleアプリケーションでカスタムベクトルを使用しています。 reallocへのコールで、ペブルがクラッシュしています。Pebbleは `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); 

ログはAことを示していますPPは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 

は、ここに私が試したものです:

  • コードはGCCとクランの両方で正常に動作します(!)。
  • は私がpoint_arraypoint_array->pointsがnullでないと
  • new_sizepoint_array->pointsの既存のサイズよりも大きいことを確認しました。
  • 私はthis issueを見ましたが、これは当てはまりません。
  • point_array_createの下部にあるreallocを呼び出してみましたが、正常に動作します。 point_array_resizeでは動作しません。
+3

初期容量が「0」の場合、サイズ変更コードは機能しません。サイズ変更時に容量がゼロでないことを確認する必要があります。 – chqrlie

+0

@chqrlie良い点 - 容量はゼロではなく、 'point_array-> points'には何かがあります。たとえば、 'point_array-> points [0] .x == 10' –

+2

プログラムの他の部分に隠れたメモリ違反があるかもしれません。プログラムやプログラムの一部がx86 Linuxで動作する場合は、valgrindを試して、プログラムに関連するエラーがないことを確認してください。 – user172818

答えて

3

point_array_pushでは、ポイントのサイズを変更する必要があるかどうかをテストしますが、テストは間違っています。長さが容量を超えた場合にのみサイズを変更します。これは、すでに配列をオーバーランしたことを意味します。

代わりに、長さが容量に達しているかどうかを確認してください。

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"); 
    }