gpt4 book ai didi

c - 未初始化的值由堆栈分配 valgrind C 创建

转载 作者:行者123 更新时间:2023-12-02 08:33:05 24 4
gpt4 key购买 nike

setlocale(LC_ALL,"pt_PT.UTF-8");
FILE *vocabulario = fopen(*(++argv),"r");
FILE *original = fopen(*(++argv),"r");
FILE *convertido = fopen(*(++argv),"w");
if (vocabulario == NULL || original == NULL || convertido == NULL){
printf("Não foi possível abrir um dos ficheiros");
return 1;
}
char delimitador = '\t';
TNode * root = NULL;
Conversor * temp = NULL;
char linhaLida[BUFFER];
char linhaTemp[BUFFER];
char linhaEscrever[BUFFER];
int i = 0;
while(fgets(linhaLida,BUFFER,vocabulario) != NULL){
if ( !criarConversor(&temp,linhaLida,delimitador) ) continue;
insertNodeViciado(&root,temp);
i++;
}

/* criarConversor implementation*/
20 int criarConversor(Conversor ** temp,char * stringAUsar,char delimitador){
21 int contador = obterNumeroDelimitadores(stringAUsar,delimitador);
22 char delimitadorInterno[] = {delimitador,'\n'};
23 if (contador == 0) return 0;
24 *temp = malloc(sizeof(Conversor));
25 verificarAlocacao(*temp);
26 (*temp)->original = obterStringAlocada(stringAUsar,delimitadorInterno);
27 if (contador == 1){
28 (*temp)->preferencia = obterStringAlocada(NULL,delimitadorInterno);
29 (*temp)->opcoes = NULL;
30 } else {
31 (*temp)->preferencia = NULL;
32 (*temp)->opcoes = malloc((contador+1)*sizeof(char *));
33 verificarAlocacao((*temp)->opcoes);
34 int i = 0;
35 while(i<contador) *(((*temp)->opcoes)+i++) = obterStringAlocada(NULL,delimitadorInterno);
36 *(((*temp)->opcoes)+i) = NULL;
}
37 return 1;



typedef struct conversor{
char * original;
char * preferencia;
char ** opcoes;
} Conversor;

Conditional jump or move depends on uninitialised value(s)
==2306== at 0x40AB01E: strtok (strtok.S:165)
==2306== by 0x8048E1E: criarConversor (Conversor.c:35)
==2306== by 0x8048984: main (main.c:24)
==2306== Uninitialised value was created by a stack allocation
==2306== at 0x8048D18: criarConversor (Conversor.c:20)


/*Gets the token,checks to see if there was a token,allocates on the heap and returns the pointer to the heap allocated string*/
char * obterStringAlocada(char * string,char * delimitador){
char * token = strtok(string,delimitador);
verificarAlocacao(token);
char * alocada = strcpy(malloc(strlen(token)+1),token);
return alocada;
}
/*Counts how many delimiters there is on the string*/
int obterNumeroDelimitadores(char * string,char delimitador){
int contador = 0;
int i = 0;
while (*(string+i) != '\0') if (*(string+i++) == delimitador)contador++;
return contador;
}
/* checks if the memory was properly allocated,which why its always called after malloc*/
void verificarAlocacao(void * verificar){
if (verificar == NULL){
printf("Não foi possível alocar a memória necessária\nO programa vai encerrar");
exit(1);
}
}

Valgrind 给我未初始化的值是由 criarConversor() 实现中的堆栈分配创建的。

我的问题是:如何将值取消初始化? delimitador 和其他两个一样是一个集合变量。如果有人说 linhaLida 没有初始化,我可以理解,除非代码永远不会到达 if(!criarConversor()) 除非 linhaLida 是由 fgets 函数编写的。

最佳答案

问题出在这里:

char delimitadorInterno[] = {delimitador,'\n'};

// ...

char * token = strtok(string,delimitador);

strtok 的第二个参数应该指向一个 string,它是要查找的分隔符。但是,您将指针传递给两个不构成字符串的字符,从而导致未定义的行为,当 strtok 读取超过 '\n' 时,valgrind 会捕获该行为。

要解决此问题,请更改为:

char delimitadorInterno[] = { delimitador,'\n', 0 };

或许

char delimitadorInterno[] = { delimitador, 0 };

我猜你打算只使用定界符作为分隔符(而不是定界符后跟换行符的顺序)。由于 fgets 的结果只能在末尾有一个换行符,因此带有 \n 的版本将永远不会匹配任何内容,除非该行以 delimiter 结尾,在这种情况下它将匹配一次。

关于c - 未初始化的值由堆栈分配 valgrind C 创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24727764/

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