打印FIFO阵列时出现问题

问题描述

我正在尝试制作一个先进先出数组,但是由于某些原因,我数组中的某些值打印的是0,而不是实际值。 到目前为止,我已经尝试打印代码中的每个值,寻找导致该问题的原因,但是我几乎是C语言的初学者,我不知道如何才能更好地解决代码中的错误

这是编译器正在打印的内容,第一列是数组的开始,第二列是结束。 qtde是数组中有多少个值,tam是数组的大小。 | x |中的数字是imprimir_fila'for'中的值'i':

--------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,50);
      fila_inserir(f,60);
      fila_inserir(f,70);
      
    
      fila_imprimir(f);
    }

抱歉,这是我在Stack Overflow中的第一个问题,我将提供一些技巧来帮助我更好地解释我的问题。感谢您的关注!

解决方法

插入三个元素后,您将拥有f->fim == 2fim->qtde == 3,这很好。删除一个元素时,您将fim->qtde减1,因此它现在的值为2,大概是因为您仅保留了“活动”元素的数量。因此,verifica_aumenta中的测试注意到fim->qtde小于等于3的f->tam,因此不会扩大缓冲区。但是fila_inserirf->fim++,所以现在f->fim == 3,并且在下一行写入f->vetor[f->fim]会使缓冲区溢出。之后,您的行为不确定,一切都会发生。

在我看来verifica_aumenta中的测试应该是if (f->fim < f->tam - 1) return;,否则您可能想以其他方式重新设计逻辑。 (您也可以通过使用realloc()来简化该功能,而不是实质上是手工重新创建它。)

我使用valgrind找到了这个。如果要使用malloc在C中进行编程,则必须学习如何使用此功能或类似的malloc检查器。