在C中释放内存的问题

时间:2017-09-13 17:47:18

标签: c memory malloc

我正在编写一个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(&registro,&registro_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);

}

3 个答案:

答案 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

如果你不必混淆mallocfree,生活会更简单。

<小时/>

  1. 这仅适用于C99或更高版本;否则,您需要使用文字32或扩展为文字的宏,例如
    
    #define REGISTRO_SIZE 32
    ...
    char registro[REGISTRO_SIZE+1];
    

答案 2 :(得分:0)

所以,正如我在原始评论中已经说过的那样,你需要注意实际上strtok()的作用。也就是说,它不会为您提供包含原始字符串某些部分的单独内存块。相反,它为原始内存块中的指针提供了指针。从这个角度来看,您无法在任何此类派生指针上调用free(),因为a)它们都不会指向整个(原始)字符串,并且b)free()只会成功释放原始地址所指向的内存。

因此,为了防止您的代码崩溃,您需要将原始指针存储在其他位置,并在最后使用该保存的指针调用free()