gpt4 book ai didi

c - 值在 while 循环之外消失,即使保存到 malloc 变量

转载 作者:太空宇宙 更新时间:2023-11-04 06:23:16 25 4
gpt4 key购买 nike

我创建了一个名为 Utype 的结构,其中包含不同的变量。如果我想要 t,那么我将调用 Utype->t

现在,我正在使用 fgets 从输入文件中检索数据。

代码是:

#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;

调用此read_file 函数后,我尝试打印

u_coarse->ultimateT

但是它说

Conditional jump or move depends on uninitialised value(s)

当我使用 Valgrind 时。一段时间以来,我一直在试图弄清楚为什么它会给我这个内存错误。任何帮助都感激不尽。

2015 年 5 月 31 日编辑:

感谢大家的参与。我附上了我对改进所做的调整后的代码。我仍然得到和以前一样的错误。 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)

哪里:

main.c:23 

是我打印出来的地方:

u_coarse->ultimateT

编辑代码:

#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;
}

我的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);

我的结构是:

typedef struct {
double ultimateT;
}Utype;

抱歉,我一直尽量不展示太多,因为这是为了研究。

最佳答案

你的代码有几个问题

  1. 您永远不会检查 strtok() 是否失败,这可能会导致 valgrind 报告它正在报告的内容,或者其他原因,因为它会导致未定义的行为。

    <
  2. 你使用 strlen() 非常错误,strlen() 循环遍历字符串,这意味着在每次迭代中你循环相同的次数。你必须存储值并使用存储的值,它不仅更高效,还使你的代码更漂亮。

  3. 循环永远不会结束,因为您没有重新分配 end_of_file 顺便说一句,这是该变量的更糟糕的名称,您应该这样做

    while (current_line = fgets(buffer, sizeof(buffer), input_file)) ...
  4. 当您可以使用 memset() 时,您正在用手动编写的循环填充 buffer 数组。

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

    在句法上会做得更好,而且效率会更高,而且 nul 会终止 buffer,而您没有这样做。

  5. 你永远不会检查 fopen() 是否成功,这也会导致未定义的行为,你必须检查每个函数调用是否按预期工作,其中大部分返回特殊值或设置特殊变量来指示问题何时发生,未能检查错误会使您的代码非常不稳定,如果我是您的老板,我会解雇您。别误会,我这么说是因为如果您听从我的建议,您将编写出更健壮的代码,并且遇到的问题也会少很多。

  6. 这个

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

    不好的原因有几个

    1. 你不应该自己循环,使用memmove()相反。

      size_t length = strlen(lines_temp);
      memmove(lines_temp, lines_temp + 1, length);
    2. 如果你自己写循环,最有效的方法是

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

关于c - 值在 while 循环之外消失,即使保存到 malloc 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30553208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com