0

我正在尝试实现一个在通用值节点列表(指向 void 的指针)上运行的程序。该程序的工作原理如下:读取输入文件的每一行,翻译每一行,解释并执行一个功能。

执行加法、减法、归一化、距离、增量、减量等功能……用几乎是浮点向量的节点的值运行。

编译使用:g+ +-g-Wall-Wextra-Werror-pedantic main.cpp -o metabasicos.cpp metintermedios.cpp metavanzados.cpp eda.exe 我没有问题。

通过使用 Valgrind,已经设法消除了所有潜在的内存泄漏和错误,但我喜欢并且无法抗拒把它放进去。

(valgrind - tool = memcheck - leak-check = full - show-reachable = yes./eda.exe)

这就是整个 main.cpp

int main(){
    Lista *L = create_list();
    char *mystring = NULL;
    char *str, *charv1, *charv2, *simbol;
    char *vec = NULL;
    int operation, Lsize, v1, v2, res;       /
    vector *auxv1 = NULL;
    vector *auxv2 = NULL;
    Nodo *ultimo = NULL; 
    str = charv1 = charv2 = simbol = NULL;

while (fgets (mystring ,100 , stdin) != NULL){  // line 21, where the errors happens    
    sscanf (mystring,"%s",str); 
res = strlen (str);                         /

    if(mystring[0] == 'p') operation = 1;           // print
    else if(mystring[0] == 'i') operation = 2;      // increase
    else if(mystring[0] == 'd') {
        if(mystring[1] == 'i') operation = 4;         // distance
        else if(mystring[1] == 'e') operation = 5;    // decrease
        else operation = 10;                          // destroy
    }                 
    else if(mystring[0] == 'n') {
        if (mystring[1] == 'e') operation = 13;         //nearest
        else{
            if (res == 4) operation = 7;                // norm
            else operation = 6;                         // normalize
        }                           
    }       
    else if(mystring[0] == 'c'){
        if (mystring[1] == 'r') operation = 11;       // create
        else operation = 12;                          // clone
    }
    else{
        sscanf (mystring,"%s %s",str, simbol);
        if (simbol[0] == '+') operation = 8;        // +
        else if(simbol[0] == '-') operation = 9;    // -  
        else operation = 3;                         // dot
    }

    switch(operation)
    {
    case 1 :                                        // print
    sscanf (mystring,"%s %s",str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        print(auxv1);
        L->actual = ultimo;

    }

    break;
    case 2 :                                        // increase
    sscanf (mystring,"%s %s %s",str, charv1, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        incr(auxv1, auxv2); 
        for (int i = v1; v1>Lsize-i; i++) next(L);
        L->actual->valor = (void*)auxv1;
        ultimo = L->actual;
    }

    break;
    case 3 :                                        // dot
    sscanf (mystring,"%s %s %s",charv1, str, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        printf("%f\n", dot(auxv1, auxv2));
    }

    break;
    case 4 :                                        // distance
    sscanf (mystring,"%s %s %s", str, charv1, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        printf("%f\n", distance(auxv1, auxv2));
    }

    break;
    case 5 :                                        // decrease 
    sscanf (mystring,"%s %s %s",str, charv1, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        decr(auxv1, auxv2);
        for (int i = v1; v1>Lsize-i; i++) next(L);
        L->actual->valor = (void*)auxv1;
        ultimo = L->actual;
    }

    break;
    case 6 :                                        // normalize 
    sscanf (mystring,"%s %s",str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        normalize(auxv1);
        L->actual->valor = (void*)auxv1;
        ultimo = L->actual;
    }

    break;
    case 7 :                                        // norm 
    sscanf (mystring,"%s %s",str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        printf("%.3f\n", norm(auxv1));
        L->actual = ultimo;
    }

    break;
    case 8 :                                        // + 
    sscanf (mystring,"%s %s %s", charv1, str, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        insert(L,crear_nodo_floatvec(add(auxv1, auxv2)));
        ultimo = L->actual;
        print((vector*)(current(L))->valor);
        Lsize++;
    }

    break;
    case 9 :                                        // - 
    sscanf (mystring,"%s %s %s", charv1, str, charv2);
    v1 = strtol((charv1+1) , NULL , 10);
    v2 = strtol((charv2+1) , NULL , 10);
    if (v1 > Lsize || v2 > Lsize) printf ("ERROR");
    else {
      for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        for (int i = v2; v2>Lsize-i; i++) next(L);
        auxv2 = (vector*)(current(L))->valor;
        L->actual = ultimo;
        insert(L,crear_nodo_floatvec(sub(auxv1, auxv2)));
        ultimo = L->actual;
        print((vector*)(current(L))->valor);
        Lsize++;
    }

    break;
    case 10 :                                       // destroy
    sscanf (mystring, "%s %s", str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        if (v1 == Lsize) {          
        ultimo = L->actual->siguiente;  //si eliminamos el último, asignamos el último al anterior //ojo
        remove(L);
        Lsize--;
        }
        else {
        remove(L);
        Lsize--;
        L->actual = ultimo; //ojo
        }
    }

    break;
    case 11 :                                       // create  
    vec = (char *)malloc(sizeof(char)*93);      //100 - tamaño de str
    sscanf (mystring, "%s %s", str, vec);
    printf("%s %s \n", str, vec);
    insert(L, crear_nodo_floatvec(create_vector(NumsVector(vec,strlen(vec)), getfloat(vec)))); //Creamos un nodo cuyo valor sea un vector de floats y lo insertamos en la lista
    ultimo = L->actual;     //ojo
    Lsize++;

    break;
    case 12 :                                       // clone
    sscanf (mystring, "%s %s", str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        insert(L,crear_nodo_floatvec(create_vector(auxv1->size, auxv1->data))); //Creamos una copia del nodo indicado y lo insertamos
        ultimo = L->actual; //ojo
        Lsize++;
    }  

    break;      
    case 13 :                                       // nearest := vector* nearest(Lista* l, vector* v); *
    sscanf (mystring,"%s %s",str, charv1);
    v1 = strtol((charv1+1) , NULL , 10);
    if (v1 > Lsize) printf ("ERROR");
    else {
        for (int i = v1; v1>Lsize-i; i++) next(L);
        auxv1 = (vector*)(current(L))->valor;
        print(nearest(L,auxv1));
        L->actual = ultimo;
    }

    break;
    default :
    printf("operation value is: %d\n", operation);

    break;

    operation = 0;
}

}

这里有一个文件,其中包含一些基本功能的实现以及节点向量和列表的实现:

typedef struct {
  float* data;
  int size;
}vector;
  struct Nodo{
  void* valor;
  struct Nodo* siguiente;
};
struct Lista{
  Nodo* primero;
  Nodo* actual;
};
vector *create_vector(int n, float* data){
    vector *newvect = (vector*)malloc(sizeof(*newvect));
    newvect->data = (float*)malloc(n*sizeof(float));
    memcpy(newvect->data, data, sizeof(float) * n);
    newvect->size = n;
    return newvect;
    destroy_vector(newvect);
}

void destroy_vector(vector* v){
free(v->data);
free(v);
}

void print(vector* v){
int size = v->size, i;
    if (v == NULL) printf("ERROR");
    else{
    for (i = 0; i < size; ++i)
    {
        if(i == 0) printf("[%.1f,", v->data[i]);
        else if(i == (size-1)) printf("%.1f]\n", v->data[i]);
        else printf("%.1f,", v->data[i]);
    }
}


Lista* create_list()                            //Creamos espacio en la lista
{
    Lista *L = NULL;
    return L;
}
void insert(Lista* l, Nodo* nodo){
    Nodo *Naux = (Nodo*)malloc(sizeof(nodo));
    Naux->valor = l->actual->valor;
    Naux->siguiente = l->actual->siguiente;
    l->actual = nodo;
    nodo->siguiente = Naux;
    free(Naux->siguiente);
    free(Naux->valor);
    free(Naux);
} 
bool end(Lista* l){
    return l->actual == NULL;
}
bool is_empty(Lista* l) {
    return l->actual->valor == NULL;
}
void next(Lista* l){
    if(end(l)) printf ("Error, final de lista");
    else l->actual = l->actual->siguiente;
}
void remove(Lista* l){
    if(not end(l)) {
        Nodo *Naux = (Nodo*)malloc(sizeof(Nodo));
        Naux = l->actual->siguiente;
        l->actual->valor = Naux->valor;
        l->actual->siguiente = Naux->siguiente;
        free(Naux->siguiente);
        free(Naux->valor);
        free(Naux); 
    } 
}
int size(Lista* l){
    if(not is_empty(l)) return sizeof(l->actual->valor);
    else return 0;
}
Nodo* current(Lista* l){
    return l->actual;
}

Nodo* crear_nodo(){
    Nodo *Naux = NULL; 
    return Naux;   
}
Nodo* crear_nodo_floatvec(vector* valor) {
    Nodo *Naux = crear_nodo();
    Naux->valor = (vector*)malloc(sizeof(valor));
    Naux->valor = (void*)valor;
    return Naux;
}
int NumsVector(char *linea, int size){                  
    int numsvector = 1;                                 
    int n;
    for(n = 2; n<= size; n++){                           
        if (linea[n] != '[' && linea[n] != ']'){
            if(linea[n] == 44){
            numsvector = numsvector + 1;
            }
        }
    }
    return numsvector;
    }

float* getfloat(char *vec){
        int size = strlen(vec);
        vec[size] = '\0';
        int n = NumsVector(vec,size), j = 0;
        float *vf = (float*)malloc(n*sizeof(float));
        vec[size-1]= ',';
        char *p = vec + 1;                         
        do {
            sscanf(p, "%f,", &vf[j]);                       
            while (*(p++) != ',') ;                 
        }
        while (++j < n);                    
    return vf;      
}

当我启动 Valgrind 时,它会显示下一个错误:

Memcheck, a memory error detector
==9392== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==9392== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==9392== Command: ./eda.exe
==9392== 
==9392== Invalid write of size 1
==9392==    at 0x519E244: _IO_getline_info (iogetline.c:84)
==9392==    by 0x519D06A: fgets (iofgets.c:58)
==9392==    by 0x401AA3: main (main.cpp:21)
==9392==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==9392== 
==9392== 
==9392== Process terminating with default action of signal 11 (SIGSEGV)
==9392==  Access not within mapped region at address 0x0
==9392==    at 0x519E244: _IO_getline_info (iogetline.c:84)
==9392==    by 0x519D06A: fgets (iofgets.c:58)
==9392==    by 0x401AA3: main (**main.cpp:21**)
==9392==  If you believe this happened as a result of a stack
==9392==  overflow in your program's main thread (unlikely but
==9392==  possible), you can try to increase the size of the
==9392==  main thread stack using the --main-stacksize= flag.
==9392==  The main thread stack size used in this run was 8388608.
==9392== 
==9392== HEAP SUMMARY:
==9392==     in use at exit: 0 bytes in 0 blocks
==9392==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==9392== 
==9392== All heap blocks were freed -- no leaks are possible
==9392== 
==9392== For counts of detected and suppressed errors, rerun with: -v
==9392== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)

当我尝试执行程序时,它还显示分段错误,核心转储

请问有没有人可以帮助我?大部分变量都是用西班牙语编写的,我想理解解码代码没有问题。

谢谢

4

1 回答 1

1

看看这两行:

char *mystring = NULL;

while (fgets (mystring ,100 , stdin) != NULL){

您正在取消引用NULL指针。

你确定你不想要例如

char mystring[100];
于 2013-11-02T20:22:00.573 回答