2016-12-06 8 views
-1

Я делаю программу, которая должна делать анализ кластера, но одна из моих функций не работает. В этой функции я пытаюсь объекты нагрузки (структура, которая содержит int ID (кластера), float x (положение) и float y (положение), и добавить их к кластеров (структура - int size (фактическое количество объектов, которые в нем), capacity (максимальное количество Containable объектов) и поля объектов (с объектами в нем)Загрузить объекты в C (cluster analysisis)

Это моя функция в настоящее время

assert(arr != NULL); 

// TODO 
int res = 0; 
FILE* stream = fopen(filename, "r"); 
/*if (stream == NULL) 
{ 
    return res; 
}*/ 
int cnt = 0; 
fscanf(stream, "count=%d\n", &cnt); 

struct cluster_t ** tmpArr; 
tmpArr = calloc(cnt,sizeof(struct cluster_t)); 
//struct obj_t * tmpObj; 
struct cluster_t *Cluster = NULL; 


int pos = 0; 
int id; 
float x, y; 
while(cnt != 0) 
{ 
    fscanf(stream,"%d %f %f\n", &id, &x, &y); 
    printf("%d %f %f", id, x, y); 
    init_cluster(Cluster, CLUSTER_CHUNK); 
    Cluster->obj[res].id = id; 
    Cluster->obj[res].x = x; 
    Cluster->obj[res].y = y; 
    Cluster->size = 1; 
    tmpArr[pos] = Cluster; 
    res++; 
    pos++; 
    cnt--; 

} 

Если значение возвращенного целого числа будет 0, то есть проблема с загрузкой.

Но, так или иначе, когда я пытаюсь отладки, я получаю SIGSEGV в

Cluster->obj[res].id = id; 

Любая идея? Большое спасибо

Для тех, кто просит, это init_cluster

void init_cluster(struct cluster_t *c, int cap) 

c = calloc(cap,sizeof(struct obj_t)); 
if(c!= NULL) 
{ 
    c->capacity = cap; 
    c->size = 0; 
    c->obj = NULL; 
} 
+3

'init_cluster (Cluster, CLUSTER_CHUNK);' Cluster (указатель) передается по значению. (функция предположительно выделяет и присваивает локальной переменной). Вы * можете * добавить 'assert (Cluster! = NULL);' после вызова функции – joop

+1

Это правда, вы должны опубликовать весь код, чтобы люди могли попробовать его. Или, по крайней мере, фрагмент, содержащий все функции, необходимые для воспроизведения поведения. – CodeMonkey

+0

@joop Я бы, если бы мог, я делаю это как школьный проект, и я не могу опубликовать весь код, потому что правила ..Но если вы хотите, я могу добавить Init_cluster – Brky

ответ

2

Это классическая ловушка и было дан ответ в десятки раза.

Параметры передаются по значению в C:

Это неправильно:

void init_cluster(struct cluster_t *c, int cap) 
{ 
    c = calloc(cap,sizeof(struct obj_t)); 
//^this modifies the local c variable but not the 
// Cluster variable on the calling side 
} 

Вам нужно это:

void init_cluster(struct cluster_t **c, int cap) 
{ 
    *c = calloc(cap,sizeof(struct obj_t)); 
//^this modifies the local c variable but not the 
// Cluster variable on the calling side 

    (*c)->obj.... 
} 

и назвать его так:

init_cluster(&Cluster, CLUSTER_CHUNK); 

вместо:

init_cluster(Cluster, CLUSTER_CHUNK); 

Придумайте простой пример:

void ComputeDoubleValue(int value) 
{ 
    value = value * 2; 
} 

Теперь, если вы звоните:

int a = 5; 
ComputeDoubleValue(a); 

a все равно будет 5 вместо 10:

Вы должны были бы это:

void ComputeDoubleValue(int *value) 
{ 
    *value = *value * 2; 
} 

int a = 5; 
ComputeDoubleValue(&a); 
+0

Сообщение об ошибке при изменении * c = calloc .... 'L: \ proj3 \ main.c | 87 | ошибка: несовместимые типы при назначении типа 'struct cluster_t' из типа 'void *'' – Brky

+0

Если компилирует штраф Вот. Вы что-то забыли, внимательно прочитайте мой ответ. –

+1

Возможно, он использует компилятор C++. (или он что-то забыл где-то) – joop