我正在尝试实现一个在通用值节点列表(指向 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)
当我尝试执行程序时,它还显示分段错误,核心转储
请问有没有人可以帮助我?大部分变量都是用西班牙语编写的,我想理解解码代码没有问题。
谢谢