我有一个没有指定数组大小的结构体
struct KMData{
int ndata;
int dim;
float **features;
int *assigns;
int *labels;
int nlabels;
};
。
在下面的函数中,我尝试根据给定文件的大小对特征和标签的内存进行malloc,但似乎没有对我指定的数据大小进行malloc。
struct KMData kmdata_load(char *datafile) {
ssize_t tokens;
ssize_t lines;
filestats(datafile, &tokens, &lines);
struct KMData *data = malloc(sizeof(struct KMData) + (lines * sizeof(int)) + ((tokens - (2*lines)) * sizeof(float)));
printf("tokens: %zd, lines: %zdn", tokens, lines);
data->labels = malloc(lines * sizeof(int));
data->features = malloc((tokens - (2*lines)) * sizeof(float));
ssize_t f_size = sizeof(*(data->features));
printf("size of features: %zdn", f_size);
FILE *fin = fopen(datafile, "r");
char line[3150];
int i = 0;
while (fgets(line, 3150, fin)) {
data->ndata++;
char *token = strtok(line, " t");
data->labels[data->ndata-1] = atoi(token);
float feats[(tokens/lines)-2];
int f = 0;
token = strtok(NULL, " t");
while ((token = strtok(NULL, " t"))) {
feats[f] = atof(token);
data->features[data->ndata-1][f] = atof(token);
if(i==0){
printf("token %d: %fn", f, data->features[data->ndata-1][f]);
}
f++;
}
i++;
ssize_t size = sizeof(feats)/sizeof(float);
}
fclose(fin);
return *data;
}
int main(int argc, char* argv[]){
struct KMData data = kmdata_load(argv[1]);
}
我在这里错过了什么吗?
当我打印出特征的大小时,它给出的是8,这比我期望的要小得多。
看了评论和回答后,我试着做
struct KMData *data = malloc(sizeof(struct KMData));
data->labels = malloc(lines * sizeof(int));
然后
data->labels[data->ndata-1] = atoi(token);
,但它给了我分割错误,所以我仍然没有正确分配数组?
当结构体包含指针时,只为该结构体分配空间。这将为指针分配空间,但它们将指向垃圾。
struct KMData *data = malloc(sizeof(struct KMData));
然后分配空间并分配给指针。
data->labels = malloc(lines * sizeof(int));
当我打印出特征的大小时,它给出了8,这比我期望的要小得多。
结构体只存储指针,在现代计算机上通常是64位(8字节)。这就是sizeof(data->features)
等于8的原因。您无法获取分配给data->features
的内存大小。
因为data->features
是一个float **
,所以它是一个指针列表。为指针分配空间,然后分配现有的浮点数列表。用sizeof(float*)
乘以你想要存储的列表的数量来分配。然后分配浮点数列表。
// Allocate space for a pointer to a list of floats for each line.
data->features = malloc(lines * sizeof(float*));
// Allocate space for each token (a float) in the first line
data->features[0] = malloc(tokens * sizeof(float));
malloc
不清除分配内存,它将包含之前在它中的任何内容。有时这是0,通常是垃圾。您还必须初始化该结构体的所有成员以确保。
data->ndata = 0;
data->dim = 0;
data->nlabels = 0;