#c #segmentation-fault #cjson
#c #сегментация-ошибка #cjson
Вопрос:
Я не могу исправить эту ошибку:
После возврата векторной структуры и ее печати (main.c) я получаю ошибку seg. EXC_BAD_ACCESS обычно означает, что указанный адрес памяти не выделен.
Но я никогда не освобождал обработанный JSON (cJSON_Delete(cJSON *input_json)). Кроме того, когда я печатаю все из функции get_album_items, это работает.
Когда я пытаюсь получить доступ к выделенной cstring вне функции get_album_items, я получаю первые элементы в массиве, а затем мусор.
Вот трассировка LLDB:
Process 1937 launched: '/Users/hugo/Git/libopenTIDAL_Dynamic/tests/a.out' (x86_64)
Testing: At Night
Testing: Floating Dogs
Testing: Quiet And Alone
Testing: Close-Up
Testing: Slow Water
Testing: Dressing The Wound
Testing: Birdy's Flight
Testing: Slow Marimbas
Testing: The Heat
Testing: Sketchpad With Trumpet And Voice
Testing: Under Lock And Key
Testing: Powerhouse At The Foot Of The Moutain
Items: 12
TotalNumberOfItems: 12
Limit: 50
Current Index: 0
Title: At Night
Current Index: 1
Title: Floating Dogs
Current Index: 2
Title: Quiet And Alone
Current Index: 3
Title: Close-Up
Current Index: 4
Title: Slow Water
Current Index: 5
Title: Dressing The Wound
Current Index: 6
Title: uM����
Current Index: 7
Title: `j
Current Index: 8
Title: The Heat
Current Index: 9
Title: L�E��E�
Current Index: 10
Process 1937 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00007fff203885d2 libsystem_platform.dylib`_platform_strlen 18
libsystem_platform.dylib`_platform_strlen:
-> 0x7fff203885d2 < 18>: pcmpeqb (%rdi), %xmm0
0x7fff203885d6 < 22>: pmovmskb %xmm0, %esi
0x7fff203885da < 26>: andq $0xf, %rcx
0x7fff203885de < 30>: orq $-0x1, %rax
Target 0: (a.out) stopped.
Разбор строки JSON
void parse_string(cJSON *object, char **string)
{
if (cJSON_IsString(object) amp;amp; (!cJSON_IsNull(object)))
{
/* object->valuestring was allocated by cJSON */
*string = object->valuestring;
}
else
{
*string = NULL;
}
}
Векторная структура:
typedef struct vector
{
void **items;
int capacity;
int total;
int status;
size_t limit;
size_t offset;
size_t totalNumberOfItems;
void *json;
void *jsonManifest;
} vector;
Get_Album_Items:
vector get_album_items(const size_t albumid, const size_t limit, const size_t offset)
{
vector v;
char *endpoint;
char baseparams[50];
/* allocate vector in heap (init size 4) */
vector_init(amp;v);
/* concatenate url endpoint amp; baseparams */
endpoint = url_cat("albums/", albumid, "/items", 0);
snprintf(baseparams, 50, "countryCode=%samp;limit=%zuamp;offset=%zu", countryCode,
limit, offset);
/* perform request */
curl_model req = curl_get(endpoint, baseparams);
free(endpoint);
if (req.status != -1)
{
/* parse returned json with cJSON */
cJSON *input_json = json_parse(req.body);
if (req.responseCode == 200)
{
cJSON *items = cJSON_GetObjectItem(input_json, "items");
cJSON *item = NULL;
cJSON *limit = cJSON_GetObjectItem(input_json, "limit");
cJSON *offset = cJSON_GetObjectItem(input_json, "offset");
cJSON *totalNumberOfItems = cJSON_GetObjectItem(input_json, "totalNumberOfItems");
size_t i = 0;
if (cJSON_IsArray(items))
{
items_model track[cJSON_GetArraySize(items)];
cJSON_ArrayForEach(item, items)
{
cJSON *innerItem = cJSON_GetObjectItem(item, "item");
/* parse json values */
json_items_model processed_json = json_parse_items(innerItem);
/* parse values to items_model struct*/
track[i] = parse_items_values(processed_json, i);
/* add items_model struct to vector */
vector_add(amp;v, amp;track[i]);
i = 1;
}
}
parse_number(limit, amp;v.limit);
parse_number(offset, amp;v.offset);
parse_number(totalNumberOfItems, amp;v.totalNumberOfItems);
v.status = 1;
}
else
{
v.status = parse_status(input_json, req, albumid, NULL);
}
v.json = input_json;
free(req.body);
return v;
}
else
{
free(req.body);
v.status = -1;
fprintf(stderr, "[Request Error] Album %zu: CURLE_OK Check failed.n", albumid);
return v;
}
}
Main.c
int main()
{
init("/Users/hugo/Documents/oT-config.json");
vector tracks = get_album_items(93560013, 50, 0);
if (tracks.status == 1)
{
printf("Items: %dn", tracks.total);
printf("TotalNumberOfItems: %zun", tracks.totalNumberOfItems);
printf("Limit: %zun", tracks.limit);
int i;
for (i = 0; i < tracks.total; i)
{
items_model *Value;
Value = (items_model *)tracks.items[i];
printf("Current Index: %dn", i);
printf("Title: %sn", Value->title);
}
}
}
Спасибо за вашу помощь!
Комментарии:
1.
vector
не объявлено2. @stark да, это так. Я также могу предоставить структуру typedef.
3. Полный обратный путь (вы компилируете с включенной отладочной информацией, верно?) было бы полезно.
4.
v.items
никогда не устанавливается
Ответ №1:
Обновление: используемая мной реализация динамического массива выделяет только массив указателей void, которые при использовании присваиваются типам. Выделение массива struct напрямую устраняет ошибку segfault и является более чистым.
int capacity = 4;
items_model *item = (items_model *) malloc(sizeof(items_model)* capacity);