我无法修复此错误:
返回向量结构并打印它(main.c)后,我得到一个段错误。EXC_BAD_ACCESS 通常意味着指向的内存地址没有分配。
但我从未释放解析过的 JSON (cJSON_Delete(cJSON *input_json))。此外,当我从 get_album_items 函数打印所有内容时,它可以工作。
当我尝试在 get_album_items 函数之外访问分配的 cstring 时,我得到数组中的第一个项目,然后是垃圾。
这是 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) && (!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(&v);
/* concatenate url endpoint & baseparams */
endpoint = url_cat("albums/", albumid, "/items", 0);
snprintf(baseparams, 50, "countryCode=%s&limit=%zu&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(&v, &track[i]);
i += 1;
}
}
parse_number(limit, &v.limit);
parse_number(offset, &v.offset);
parse_number(totalNumberOfItems, &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;
}
}
主程序
int main()
{
init("/Users/hugo/Documents/oT-config.json");
vector tracks = get_album_items(93560013, 50, 0);
if (tracks.status == 1)
{
printf("Items: %d\n", tracks.total);
printf("TotalNumberOfItems: %zu\n", tracks.totalNumberOfItems);
printf("Limit: %zu\n", tracks.limit);
int i;
for (i = 0; i < tracks.total; ++i)
{
items_model *Value;
Value = (items_model *)tracks.items[i];
printf("Current Index: %d\n", i);
printf("Title: %s\n", Value->title);
}
}
}
谢谢您的帮助!