我是C新手所以我相信由于指针和内存分配缺乏基础知识,我的代码中出现了一个新手错误。
我有一个表示数字数据的二进制文件,我正在尝试读取和存储该数据。 这是打开文件的代码的第一部分,在文件中读取少量数字,用于为struct emxArray_real_T分配足够的内存。
STRUCT:
struct emxArray_real_T
{
real_T *data;
int32_T *size;
int32_T allocatedSize;
int32_T numDimensions;
boolean_T canFreeData;
}
主要的第一部分:
# include <stdio.h>
# include <stdlib.h> /*atoi*/
# include <assert.h>
int main(int argc, char** argv){
//Variable declaration
unsigned short numOfSums;
unsigned long chSum, countRSN, countPeriods;
int i,j;
FILE *file;
//Open file
file = fopen("testBin.bin","rb");
//Read first number that tells how many items to skip
fread(&numOfSums, 2, 1,file);
//Skip that many items
for (i=0;i<numOfSums;i++){
fread(&chSum,4,1,file);
}
//Read next two numbers
fread(&countRSN,4,1,file);
fread(&countPeriods,4,1,file);
//Allocate enaugh space based on the size of countRSN and countPeriods
struct emxArray_real_T* Sa_1 = malloc(sizeof(*Sa_1)*1);
assert(Sa_1 != NULL);
Sa_1->data=malloc(sizeof(real_T)*countRSN*countPeriods);
Sa_1->size=malloc(sizeof(int32_T)*2);
Sa_1->allocatedSize=(sizeof(int32_T)*1);
Sa_1->size[0]=countRSN;
Sa_1->size[1]=countPeriods;
struct emxArray_real_T *Sa_2;
Sa_2=(struct emxArray_real_T*)malloc(sizeof(struct emxArray_real_T)*1);
assert(Sa_2 != NULL);
Sa_2->data=(real_T*)malloc(sizeof(real_T)*countRSN*countPeriods);
Sa_2->size=malloc(sizeof(int32_T)*2);
Sa_2->allocatedSize=(sizeof(int32_T)*1);
Sa_2->size[0]=countRSN;
Sa_2->size[1]=countPeriods;
struct emxArray_real_T *sVs30;
sVs30=(struct emxArray_real_T*)malloc(sizeof(struct emxArray_real_T));
sVs30->data=malloc(sizeof(real_T)*countRSN);
sVs30->size=malloc(sizeof(int32_T)*1);
sVs30->allocatedSize=(sizeof(int32_T)*1);
sVs30->size[0]=countRSN;
这是问题所在。如果我试图存储我的数据并转置它,因为它的顺序不正确,我会得到分段错误,
for (i=0;i<countRSN;i++){
for (j=0;j<countPeriods;j++){
fread(&Sa_1->data[countRSN*j+i],8,1,file);
}
}
如果我这样尝试,它就可以了:
for (i=0;i<countRSN*countPeriods;i++){
fread(&Sa_1->data[i],8,1,file);
}
.
.
.
fclose(file);
free(Sa_1);
free(Sa_2);
free(sVs30);
return 0;
}
答案 0 :(得分:0)
每次调用fread
,您都会读取8个字节并将其写入数组。在我看来,你把它们存放在正确的位置。如果sizeof(real_T)
小于8,则必须预期出现分段错误。
如果sizeof(real_T)
小于8,说它的大小为4 *,&Sa_1->data[countRSN*countPeriods-1]
将在有效位置写入4个字节中的4个,其他4个字节将写入分配范围之外
为什么代码会在一个案例中崩溃而另一个案例却不会崩溃?首先,通过访问未分配的内存,您处于未定义的行为范围内。该程序不再需要以明确定义的方式运行。其次,如果文件流已经到达结尾,fread
不会写入缓冲区。在您的示例中工作的代码仅在文件足够长时写入最后一个地址。
*在Matlab中,real_T
是4或8个字节,具体取决于定义。如果它是4个字节,那么op给出的代码应该抛出一个段错误。
答案 1 :(得分:0)
您假设的类型大小。在你使用4,2,8等的任何地方使用sizeof
。同时确保fread可以使用short int,我怀疑
答案 2 :(得分:0)
struct emxArray_real_T* Sa_1 = malloc(sizeof(*Sa_1)*1);
要
struct emxArray_real_T* Sa_1 = malloc(sizeof(struct emxArray_real_T));