【问题标题】:Pebble crashes on `realloc`, but only in a certain function [closed]Pebble 在 `realloc` 上崩溃,但仅限于某个函数 [关闭]
【发布时间】:2016-11-29 02:44:28
【问题描述】:

我在 Pebble 应用程序中使用自定义矢量。 Pebble 在调用 realloc 时崩溃。

ma​​in.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);

日志显示应用在调用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 和 Clang (!) 上运行良好。
  • 我验证了point_arraypoint_array-&gt;points 不为空并且
  • new_size 大于 point_array-&gt;points 的现有大小。
  • 我查看了this issue,似乎不适用。
  • 我尝试在point_array_create 的底部调用realloc,效果很好。它在point_array_resize 中不起作用。

【问题讨论】:

  • 如果初始容量为0,则resize代码不起作用。调整大小时应确保容量不为零。
  • @chqrlie 好点 - 容量不为零,point_array-&gt;points 里面有东西。例如point_array-&gt;points[0].x == 10
  • 程序的其他部分可能存在隐藏的内存违规。如果您的程序或程序的一部分在 x86 linux 上运行,请尝试使用 valgrind 并确保您没有看到任何与您的程序相关的错误。
  • 为什么你在resize而不是create重新分配一个额外的槽
  • foo = realloc(foo, some_size); 总是错误(除非保证fooNULL,但然后只写NULL 而不是foo),因为它是可能的内存泄漏。 realloc 在失败时不会 free

标签: c memory-management realloc pebble-sdk


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2016-07-07
    • 2012-11-27
    • 2018-12-22
    • 1970-01-01
    • 2018-03-16
    • 2013-08-23
    相关资源
    最近更新 更多