【发布时间】:2014-07-13 23:17:45
【问题描述】:
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 linhaLida[BUFFER],linhaTemp[BUFFER],linhaEscrever[BUFFER];但是如果没有self-contained example 的代码给出这个错误,就很难给出准确的答案。 -
我不喜欢你的格式,也不喜欢在打开文件时使用序列点 (
,)。 -
如果我添加 linhaLida[BUFFER] = 0;它仍然给我同样的错误,我什至为 temp 变量分配了空间,它仍然给我错误。此外 linhaLida 将在 fgets 函数到达 if 之前对其进行初始化,如果 fgets 返回 NULL 则 if 是不可达的,我认为这不会是一个问题;抱歉摆弄比特我现在就改变它
-
我的意思是添加 linhaLida[BUFFER] = {0};我有大约 0.5GB 的测试用例,没有一个给我这个错误,只有 valgrind 似乎做到了。此外,如果 fgets 返回 NULL 则 if 代码无法访问,如果 fgets 不返回 NULL 则初始化 linhaLida 并且我认为不存在未初始化的问题?
-
@FiddlingBits 逗号分隔符不是序列点
标签: c