我正在编写一个C程序并且我使用了一些内存,当我尝试释放它时,我遇到了分段错误。不知道我做错了什么。这是功能: 我在释放令牌时只会收到错误,而不是registro。
void cargarArchivo(struct fila *arregloArchivo){
FILE *csv = fopen("datos_meteorologicos.CSV","r");
char *registro;
char *token;
struct fila local;
int i;
int j;
registro = (char *)malloc(sizeof(char));
token = (char *)malloc(100*sizeof(char));
size_t characters;
size_t registro_size = 32;
if(registro==NULL || arregloArchivo==NULL){
printf("%s\n", "Problemas alocando memoria, no hay suficiente");
exit(1);
}
while(-1 != getline(®istro,®istro_size,csv)){
token = strtok(registro,",");
for(j=0;j<cantDatos+1;j++){
if(j<1){
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
token = strtok(NULL,",");
}
else if(j==1){
local.numero = atoi(token);
//printf("numero:%d\n",local.numero );
token = strtok(NULL,",");
strcpy(local.estacion,token);
//printf("estacion:%s\n",local.estacion );
token = strtok(NULL,",");
local.localidad = atoi(token);
//printf("loca%d\n",local.localidad );
token = strtok(NULL,",");
strcpy(local.fecha,token);
//printf("fec%s\n",local.fecha );
token = strtok(NULL,",");
local.temperatura = atof(token);
//printf("temperatura%f\n",local.temperatura );
token = strtok(NULL,",");
local.porcentajeHumedad = atof(token);
//printf("porHum: %f\n",local.porcentajeHumedad );
token = strtok(NULL,",");
local.puntoRocio = atof(token);
//printf("punto rocio: %f\n",local.puntoRocio );
token = strtok(NULL,",");
local.precipitacion = atof(token);
//printf("prec:%f\n",local.precipitacion );
token = strtok(NULL,",");
local.velocidadViento = atof(token);
//printf("velviento:%f\n",local.velocidadViento );
token = strtok(NULL,",");
strcpy(local.dirViento,token);
//printf("dirviento: %s\n",local.dirViento );
token = strtok(NULL,",");
local.rafagaMax = atof(token);
//printf("rafagamax: %f\n",local.rafagaMax );
token = strtok(NULL,",");
local.presion = atof(token);
//printf("presion:%f\n",local.presion );
token = strtok(NULL,",");
local.radiacionSolar = atof(token);
//printf("rad:%f\n",local.radiacionSolar );
token = strtok(NULL,",");
local.tempSuelo1 = atof(token);
//printf("tempSuelo1:%f\n",local.tempSuelo1 );
token = strtok(NULL,",");
local.tempSuelo2 = atof(token);
//printf("tempSuelo2:%f\n",local.tempSuelo2 );
token = strtok(NULL,",");
local.tempSuelo3 = atof(token);
//printf("tempSuelo3:%f\n",local.tempSuelo3 );
token = strtok(NULL,",");
local.humedadSuelo1 = atof(token);
//printf("humedad1: %f\n",local.humedadSuelo1 );
token = strtok(NULL,",");
local.humedadSuelo2 = atof(token);
//printf("humedad2: %f\n",local.humedadSuelo2 );
token = strtok(NULL,",");
local.humedadSuelo3 = atof(token);
//printf("humedad3: %f\n",local.humedadSuelo3 );
token = strtok(NULL,", ");
local.humedadHoja = atof(token);
//printf("hum hoja: %f\n",local.humedadHoja );
arregloArchivo[j-1] = local;
}else{
token = strtok(NULL,",");
local.numero = atoi(token);
//printf("num: %d\n",local.numero);
token = strtok(NULL,",");
strcpy(local.estacion,token);
//printf("estacion:%s\n",local.estacion );
token = strtok(NULL,",");
local.localidad = atoi(token);
//printf("loca%d\n",local.localidad );
token = strtok(NULL,",");
strcpy(local.fecha,token);
//printf("fec%s\n",local.fecha );
token = strtok(NULL,",");
local.temperatura = atof(token);
//printf("temperatura%f\n",local.temperatura );
token = strtok(NULL,",");
local.porcentajeHumedad = atof(token);
//printf("porHum: %f\n",local.porcentajeHumedad );
token = strtok(NULL,",");
local.puntoRocio = atof(token);
//printf("punto rocio: %f\n",local.puntoRocio );
token = strtok(NULL,",");
local.precipitacion = atof(token);
//printf("prec:%f\n",local.precipitacion );
token = strtok(NULL,",");
local.velocidadViento = atof(token);
//printf("velviento:%f\n",local.velocidadViento );
token = strtok(NULL,",");
strcpy(local.dirViento,token);
//printf("dirviento: %s\n",local.dirViento );
token = strtok(NULL,",");
local.rafagaMax = atof(token);
//printf("rafagamax: %f\n",local.rafagaMax );
token = strtok(NULL,",");
local.presion = atof(token);
//printf("presion:%f\n",local.presion );
token = strtok(NULL,",");
local.radiacionSolar = atof(token);
//printf("rad:%f\n",local.radiacionSolar );
token = strtok(NULL,",");
local.tempSuelo1 = atof(token);
//printf("tempSuelo1:%f\n",local.tempSuelo1 );
token = strtok(NULL,",");
local.tempSuelo2 = atof(token);
//printf("tempSuelo2:%f\n",local.tempSuelo2 );
token = strtok(NULL,",");
local.tempSuelo3 = atof(token);
//printf("tempSuelo3:%f\n",local.tempSuelo3 );
token = strtok(NULL,",");
local.humedadSuelo1 = atof(token);
//printf("humedad1: %f\n",local.humedadSuelo1 );
token = strtok(NULL,",");
local.humedadSuelo2 = atof(token);
//printf("humedad2: %f\n",local.humedadSuelo2 );
token = strtok(NULL,",");
local.humedadSuelo3 = atof(token);
//printf("humedad3: %f\n",local.humedadSuelo3 );
token = strtok(NULL,", ");
local.humedadHoja = atof(token);
//printf("hum hoja: %f\n",local.humedadHoja );
arregloArchivo[j-1] = local;
}
}
}
free(registro);
printf("%s\n","Fin de la carga." );
free(token);
printf("%s\n","libere token" );
fclose(csv);
}
答案 0 :(得分:1)
@Daan Gerlack在评论中回答的原因是正确的,因为您通过为其分配<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
的返回值来改变token
的值。
因此,要解决此问题,请将引用(也称为指针)存储到字符串的开头,这是唯一的指针值strtok()
将接受以指示您分配的内存块,并释放使用该引用的内存。
答案 1 :(得分:0)
您正在使用token
调用的返回值覆盖strtok
中存储的指针值;传递给free
的内容与malloc
获得的指针值不同。老实说,你根本不需要为token
分配或释放任何内存。
其次,您只为registro
分配足够的内存来存储单个字符值,而不是字符串。
坦率地说,这里不需要进行任何动态内存管理。将registro
声明为char
:
size_t registro_size = 32;
char registro[registro_size+1]; // see footnote 1
如果你不必混淆malloc
和free
,生活会更简单。
<小时/>
32
或扩展为文字的宏,例如
#define REGISTRO_SIZE 32
...
char registro[REGISTRO_SIZE+1];
答案 2 :(得分:0)
所以,正如我在原始评论中已经说过的那样,你需要注意实际上strtok()
的作用。也就是说,它不会为您提供包含原始字符串某些部分的单独内存块。相反,它为原始内存块中的指针提供了指针。从这个角度来看,您无法在任何此类派生指针上调用free()
,因为a)它们都不会指向整个(原始)字符串,并且b)free()
只会成功释放原始地址所指向的内存。
因此,为了防止您的代码崩溃,您需要将原始指针存储在其他位置,并在最后使用该保存的指针调用free()
。