简体   繁体   English

即使保存到malloc变量中,值也会在while循环外消失

[英]Value disappearing outside of while loop, even though saving to a malloc variable

I've created a struct called Utype that contains different variables. 我创建了一个名为Utype的结构,其中包含不同的变量。 If I want t then I will call Utype->t . 如果我想要t那么我将调用Utype->t

Now, I'm using fgets to retrieve data from an input file. 现在,我正在使用fgets从输入文件中检索数据。

The code is : 代码是

#include "read_file.h"

int read_file(int argc, char* argv[], Utype* u_coarse){
    int i;
    int num_length = 1024;
    FILE *input_file;
    char buffer[num_length];
    char *end_of_file;
    char *lines = NULL;
    char *lines_temp;
    int  num_time_segments=0;
    double testest=0;

    for (i=0; i<num_length; i++){
        buffer[i]=' ';
    }
    input_file = fopen(argv[1], "r");
    end_of_file = fgets(buffer, num_length, input_file);
    while (end_of_file != NULL){

        if (end_of_file[0]!= '\n' && end_of_file[0]!='%'){
            lines = strtok(end_of_file, "=");
            if (lines[strlen(lines)-1] == ' '){
                lines[strlen(lines)-1] = '\0';
            }
            lines_temp = strtok(NULL, "=");
            if (lines_temp[0] == ' '){
                for (i=1; i<strlen(lines_temp); i++){
                    lines_temp[i-1] = lines_temp[i];
                }
                lines_temp[strlen(lines_temp)-2] = '\0';
            }else{
                lines_temp[strlen(lines_temp)-1] = '\0';
            }
            if (strcmp(lines, "T") == 0){
                u_coarse->ultimateT = atof(lines_temp);
            }
        //  printf("%g\n", testest);                                                                                                                           
        }

    }
//  printf("%g\n", testest);                                                                                                                                   
//  u_coarse->burn_time = testest;                                                                                                                             

    fclose(input_file);

    return num_time_segments;

After I call this read_file function, I try to print 调用此read_file函数后,我尝试打印

u_coarse->ultimateT

But it says 但是它说

Conditional jump or move depends on uninitialised value(s)

when I use Valgrind. 当我使用Valgrind时。 I've been trying to figure out why it's giving me this memory error for a while now. 我一直在试图弄清楚为什么现在一段时间会给我这个内存错误。 Any help will be much appreciated. 任何帮助都感激不尽。

Edit May 31, 2015 : 编辑2015年5月31日

Thank you all for your input. 谢谢大家的意见。 I'm attaching the adjusted code that I did with improvements. 我将附加经过改进的调整后的代码。 I still get the same error as before. 我仍然收到和以前一样的错误。 Valgrind says: Valgrind说:

==6485== Memcheck, a memory error detector
==6485== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==6485== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==6485== Command: ../bin/main.x ../ ../example_input.inp
==6485== 
==6485== Conditional jump or move depends on uninitialised value(s)
==6485==    at 0x3BFE249CF0: __printf_fp (in /lib64/libc-2.12.so)
==6485==    by 0x3BFE24589F: vfprintf (in /lib64/libc-2.12.so)
==6485==    by 0x3BFE24F189: printf (in /lib64/libc-2.12.so)
==6485==    by 0x406CF1: main (main.c:23)

where: 哪里:

main.c:23 

is where I'm printing out : 是我要打印的地方:

u_coarse->ultimateT

Edited Code : 编辑代码

#include "read_file.h"

int read_file(int argc, char* argv[], Utype* u_coarse){

    int i;
    int num_length = 1024;
    FILE *input_file;
    char buffer[num_length];
    char *current_line;
    char *lines = NULL;
    char *lines_temp;
    int  num_time_segments=0;
    size_t length;
    size_t length_temp;

    memset(buffer, ' ', sizeof(buffer) -1);
    buffer[sizeof(buffer) - 1] = '\0';
    input_file = fopen(argv[1], "r");
    if (input_file == NULL){
        perror("Error");
        exit( EXIT_FAILURE);
    }else{
        while ( current_line =  fgets(buffer, sizeof(buffer), input_file)){
            if (current_line[0]!= '\n' && current_line[0]!='%'){
                lines = strtok(current_line, "=");
                if (lines == NULL){
                    perror("Error");
                    exit( EXIT_FAILURE );
                }
                length = strlen(lines);
                if (lines[length-1] == ' '){
                    lines[length-1] = '\0';
                }
                lines_temp = strtok(NULL, "=");
                if (lines_temp == NULL){
                    perror("Error");
                    exit( EXIT_FAILURE );
                }
                length_temp = strlen(lines_temp);
                if (lines_temp[0] == ' '){
                    memmove(lines_temp, lines_temp +1, length_temp);
                }else{
                    lines_temp[length_temp-1] = '\0';
                }
                if (strcmp(lines, "T") == 0){
                    u_coarse->ultimateT = atof(lines_temp);
                }
            }
        }
    }
    return num_time_segments;
}

My main.c file is : 我的main.c文件是

int main(int argc, char *argv[]) {

    Utype *u_coarse = (Utype*)malloc(sizeof(Utype));                         

    int num_time_segments = read_file(argc, argv, u_coarse);
    printf("%g\n", u_coarse->ultimateT);

My struct is : 我的结构是

typedef struct {
     double ultimateT;
}Utype;

Sorry, I've been trying not to show too much since this is for research. 抱歉,由于要进行研究,我一直在尝试不显示太多。

Your code has several problems 您的代码有几个问题

  1. You never check if strtok() failed or not, which can cause valgrind to report what it is reporting, or something else since it causes undefined behavior. 您永远不会检查strtok()失败,这可能导致valgrind报告所报告的内容,或者其他原因,因为这会导致未定义的行为。

  2. You use strlen() very wrong, strlen() loops through the string which means that in each iteration you are looping the same number of times. 您使用strlen()非常错误, strlen()遍历字符串,这意味着在每次迭代中,您都将循环相同的次数。 You must store the value and use the stored value, it's not only more efficient, it also makes your code prettier. 您必须存储值并使用存储的值,这不仅效率更高,而且还使代码更漂亮。

  3. The loop never ends, because you don't reassign end_of_file which is by the way the worse name for that variable, you should do it like this 循环永无止境,因为您不必重新分配end_of_file ,因为这是该变量的较差名称,所以您应该这样做

     while (current_line = fgets(buffer, sizeof(buffer), input_file)) ... 
  4. You are filling the buffer array with a manually written loop when you can use memset() 当您可以使用memset()时,将使用手动编写的循环填充buffer数组

     memset(buffer, ' ', sizeof(buffer) - 1); buffer[sizeof(buffer) - 1] = '\\0'; 

    would do a better job, syntactically and also it would be more efficient, and also would nul terminate buffer , which you didn't do. 会在语法上做得更好,而且效率会更高,并且会nul终止buffer ,而您没有这样做。

  5. You never check if fopen() succeded, which would lead to undefined behavior too, you must check that every function call worked as expected, most of them return special values or set special variables to indicate when a problem happens, failing to check for errors makes your code very unstable and if I was your boss I would fire you. 您永远不会检查fopen()成功,这也会导致未定义的行为,您必须检查每个函数调用是否按预期工作,其中大多数返回特殊值或设置特殊变量以指示何时发生问题,从而无法检查错误使您的代码非常不稳定,如果我是您的老板,我会开除您。 Don't take it wrong, I am saying this because if you follow my advice you will write more robust code, and you will have way less problems. 别误会,我说这是因为,如果您遵循我的建议,您将编写更健壮的代码,并且将减少麻烦。

  6. This 这个

     for (i = 1 ; i < strlen(lines_temp) ; i++) { lines_temp[i - 1] = lines_temp[i]; } lines_temp[strlen(lines_temp) - 2] = '\\0'; 

    is bad for several reasons 坏有几个原因

    1. You should not loop by yourself, use memmove() instead. 您不应该自己循环,而应使用memmove()

       size_t length = strlen(lines_temp); memmove(lines_temp, lines_temp + 1, length); 
    2. If you write the loop by yourself, the efficient way would be 如果您自己编写循环,则有效的方法是

       for (i = 1 ; lines_temp[i] != 0 ; i++) { lines_temp[i - 1] = lines_temp[i]; } lines_temp[i - 1] = '\\0'; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM