打印 FIFO 数组时出现问题
Trouble when printing an FIFO array
我正在尝试创建一个先进先出数组,但出于某种原因,我的数组中的某些值正在打印 0 而不是实际值。
到目前为止,我尝试打印代码中的每个值,寻找该问题的原因,但我几乎是 C 语言的初学者,我不知道如何才能更好地解决代码中的错误。
这是编译器正在打印的内容,第一列是我的数组的开头,第二列是结尾。 qtde 是数组中有多少个值,tam 是数组的大小。 |x| 中的数字'i' 来自 imprimir_fila 'for':
--------Teste--------
0, 0
0, 1
0, 2
1, 3
2, 4
2, 5
2, 6
qtde: 5
tam: 6
[30 |3|,0 |4|,0 |5|,60 |6|, 70|7|]
到目前为止,这是我的代码:
typedef enum boolean{false=0, true=1} Boolean;
typedef int TipoElemento;
typedef struct {
TipoElemento* vetor; //Array
int tam; //Size of the array
int inicio; //Start of the array
int fim; //End of my array
int qtde; //How many values there is in my array
}Fila;
Fila* fila_criar();
Boolean fila_inserir(Fila* f, TipoElemento elemento);
Boolean fila_remover(Fila* f, TipoElemento* saida);
void verifica_aumenta(Fila* f);
void fila_imprimir(Fila* f);
//Creates the array.
Fila* fila_criar(){
Fila* f = (Fila*)malloc (sizeof(Fila));
f->tam = 3;
f->qtde = 0;
f->vetor = (TipoElemento*) malloc(f->tam * sizeof(TipoElemento));
f->inicio = 0;
f->fim = -1;
return f;
}
//Add a value into the array
Boolean fila_inserir(Fila* f, TipoElemento elemento){
if(f == NULL) return false;
verifica_aumenta(f);
f->fim++;
f->vetor[f->fim] = elemento;
f->qtde++;
return true;
}
//Removes a value
Boolean fila_remover(Fila* f, TipoElemento* saida){
if(f == NULL) return false;
*saida = f->vetor[f->inicio];
if(f->inicio == f->tam) f->inicio = 0;
f->inicio = f->inicio+1;
f->qtde--;
return true;
}
//Doubles the size of the array if it hits the limit
void verifica_aumenta(Fila* f){
if(f->qtde < f->tam) return;
TipoElemento* clone = (TipoElemento*) calloc(f->tam*2, sizeof(TipoElemento));
for(int i=0; i < f->tam; i++){
clone[i] = f->vetor[i];
}
free(f->vetor);
f->tam *= 2;
f->vetor = clone;
}
//Printf
void fila_imprimir(Fila* f){
if(f == NULL) return;
printf("[");
int j, i = f->inicio;
for(j = 0; j < f->qtde; j++){
printf("%d", f->vetor[i++]);
if(j < f->qtde-1) printf(", ");
if(i > f->tam) i = 0;
}
printf("]");
printf("\n");
}
这就是我正在做的测试:
void teste(){
Fila* f = fila_criar();
TipoElemento saida;
fila_inserir(f, 10);
fila_inserir(f, 20);
fila_inserir(f, 30);
fila_remover(f, &saida);
fila_inserir(f, 40);
fila_remover(f, &saida);
fila_inserir(f, 50);
fila_inserir(f, 60);
fila_inserir(f, 70);
fila_imprimir(f);
}
抱歉我的英语不好,这是我在 Stack Overflow 中的第一个问题,我会很感激能帮助我更好地解释我的问题的提示。感谢关注!
插入三个元素后,你有f->fim == 2
和fim->qtde == 3
,这很好。当您删除一个元素时,您会递减 fim->qtde
,因此它现在的值为 2,大概是因为您只保留“活动”元素的数量。所以 verifica_aumenta
中的测试注意到 fim->qtde
小于等于 3 的 f->tam
,因此它不会扩大缓冲区。但是 fila_inserir
确实 f->fim++
,所以现在 f->fim == 3
,并且在下一行写入 f->vetor[f->fim]
会溢出缓冲区。在那之后你有未定义的行为,任何事情都可能发生。
在我看来 verifica_aumenta
中的测试应该是 if (f->fim < f->tam - 1) return;
,否则您可能想以其他方式重新设计您的逻辑。 (您还可以通过使用 realloc()
来简化该函数,而不是本质上手动重新发明它。)
我使用 valgrind 找到了这个。如果您要使用 malloc
在 C 中编程,您 必须 学习如何使用这个或类似的 malloc 检查器。
我正在尝试创建一个先进先出数组,但出于某种原因,我的数组中的某些值正在打印 0 而不是实际值。 到目前为止,我尝试打印代码中的每个值,寻找该问题的原因,但我几乎是 C 语言的初学者,我不知道如何才能更好地解决代码中的错误。
这是编译器正在打印的内容,第一列是我的数组的开头,第二列是结尾。 qtde 是数组中有多少个值,tam 是数组的大小。 |x| 中的数字'i' 来自 imprimir_fila 'for':
--------Teste--------
0, 0
0, 1
0, 2
1, 3
2, 4
2, 5
2, 6
qtde: 5
tam: 6
[30 |3|,0 |4|,0 |5|,60 |6|, 70|7|]
到目前为止,这是我的代码:
typedef enum boolean{false=0, true=1} Boolean;
typedef int TipoElemento;
typedef struct {
TipoElemento* vetor; //Array
int tam; //Size of the array
int inicio; //Start of the array
int fim; //End of my array
int qtde; //How many values there is in my array
}Fila;
Fila* fila_criar();
Boolean fila_inserir(Fila* f, TipoElemento elemento);
Boolean fila_remover(Fila* f, TipoElemento* saida);
void verifica_aumenta(Fila* f);
void fila_imprimir(Fila* f);
//Creates the array.
Fila* fila_criar(){
Fila* f = (Fila*)malloc (sizeof(Fila));
f->tam = 3;
f->qtde = 0;
f->vetor = (TipoElemento*) malloc(f->tam * sizeof(TipoElemento));
f->inicio = 0;
f->fim = -1;
return f;
}
//Add a value into the array
Boolean fila_inserir(Fila* f, TipoElemento elemento){
if(f == NULL) return false;
verifica_aumenta(f);
f->fim++;
f->vetor[f->fim] = elemento;
f->qtde++;
return true;
}
//Removes a value
Boolean fila_remover(Fila* f, TipoElemento* saida){
if(f == NULL) return false;
*saida = f->vetor[f->inicio];
if(f->inicio == f->tam) f->inicio = 0;
f->inicio = f->inicio+1;
f->qtde--;
return true;
}
//Doubles the size of the array if it hits the limit
void verifica_aumenta(Fila* f){
if(f->qtde < f->tam) return;
TipoElemento* clone = (TipoElemento*) calloc(f->tam*2, sizeof(TipoElemento));
for(int i=0; i < f->tam; i++){
clone[i] = f->vetor[i];
}
free(f->vetor);
f->tam *= 2;
f->vetor = clone;
}
//Printf
void fila_imprimir(Fila* f){
if(f == NULL) return;
printf("[");
int j, i = f->inicio;
for(j = 0; j < f->qtde; j++){
printf("%d", f->vetor[i++]);
if(j < f->qtde-1) printf(", ");
if(i > f->tam) i = 0;
}
printf("]");
printf("\n");
}
这就是我正在做的测试:
void teste(){
Fila* f = fila_criar();
TipoElemento saida;
fila_inserir(f, 10);
fila_inserir(f, 20);
fila_inserir(f, 30);
fila_remover(f, &saida);
fila_inserir(f, 40);
fila_remover(f, &saida);
fila_inserir(f, 50);
fila_inserir(f, 60);
fila_inserir(f, 70);
fila_imprimir(f);
}
抱歉我的英语不好,这是我在 Stack Overflow 中的第一个问题,我会很感激能帮助我更好地解释我的问题的提示。感谢关注!
插入三个元素后,你有f->fim == 2
和fim->qtde == 3
,这很好。当您删除一个元素时,您会递减 fim->qtde
,因此它现在的值为 2,大概是因为您只保留“活动”元素的数量。所以 verifica_aumenta
中的测试注意到 fim->qtde
小于等于 3 的 f->tam
,因此它不会扩大缓冲区。但是 fila_inserir
确实 f->fim++
,所以现在 f->fim == 3
,并且在下一行写入 f->vetor[f->fim]
会溢出缓冲区。在那之后你有未定义的行为,任何事情都可能发生。
在我看来 verifica_aumenta
中的测试应该是 if (f->fim < f->tam - 1) return;
,否则您可能想以其他方式重新设计您的逻辑。 (您还可以通过使用 realloc()
来简化该函数,而不是本质上手动重新发明它。)
我使用 valgrind 找到了这个。如果您要使用 malloc
在 C 中编程,您 必须 学习如何使用这个或类似的 malloc 检查器。