0

我想实现一个程序,对通用值节点列表(无效指针)进行操作。该程序的工作原理如下:读取翻译每行的输入文件的每一行,解释并执行一个函数。无效的写入和信号11错误valgrind

执行加法,减法,标准化,距离,增量,递减等函数运行几乎是浮点向量的节点的值。

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

通过使用Valgrind've设法消除所有潜在的内存泄漏和错误,但我喜欢和我无法拒绝的一个。

(Valgrind的 - 工具= MEMCHECK - 泄漏检查=全 - 展示 - 可达= 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) 

当我尝试执行程序这也说明我分割故障,核心转储

是否有任何人能帮助我吗? 变量的最大部分是用西班牙语写的,我想这对理解代码没有问题。

谢谢

回答

1

看theese两行:

char *mystring = NULL; 

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

你解引用NULL指针。

你确定你不想要