Escribo este post a ver si alguien me puede ayudar con una práctica que he de entregar en breves. Se trata de un programa que trabajal rcon vectores (structs) y hace distintos tipos de operaciones entre ellos. El programa lee los vectores y operaciones de el stdin.
El programa en si funciona pero al pasar el valgrint me salta con los siguientes errores.
Código:
javi@javi-HEL80C:~/practica1$ valgrind --tool=memcheck ./p1 < entrada.txt==4153== Memcheck, a memory error detector
==4153== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4153== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4153== Command: ./p1
==4153==
[9.3,1.2,87.9]
[1,1]
[0,0,1]
v1 + v2
==4153== Invalid write of size 4
==4153== at 0x400C7C: resize(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401189: add(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401851: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a148 is 0 bytes after a block of size 8 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x40121B: add(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401851: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a148 is 0 bytes after a block of size 8 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
[10.3,2.2,87.9]
v3 - v1
[-9.3,-1.2,-86.9]
incr v3 v1
==4153== Invalid read of size 4
==4153== at 0x401035: incr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401BBC: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x40104D: incr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401BBC: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a0ac is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid write of size 4
==4153== at 0x401055: incr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401BBC: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
[9.3,1.2,88.9]
decr v1 v3
==4153== Invalid read of size 4
==4153== at 0x40110C: decr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401B1D: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a0ac is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x401124: decr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401B1D: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid write of size 4
==4153== at 0x40112C: decr(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401B1D: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a0ac is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
[0,0,-1]
decr v1 v3
[-9.3,-1.2,-89.9]
v2 dot v3
==4153== Invalid read of size 4
==4153== at 0x400E09: dot(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x4019B3: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a148 is 0 bytes after a block of size 8 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
10.500000
norm v3
==4153== Invalid read of size 4
==4153== at 0x400EA5: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401CD2: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x400EBD: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401CD2: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
89.393181
v1 dot v2
==4153== Invalid read of size 4
==4153== at 0x400E21: dot(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x4019B3: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a148 is 0 bytes after a block of size 8 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
-10.500000
distance v1 v3
==4153== Invalid read of size 4
==4153== at 0x400EA5: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x4013B0: distance(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401A8D: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a41c is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4012E9: sub(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x4013A8: distance(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401A8D: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x400EBD: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x4013B0: distance(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401A8D: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a41c is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4012E9: sub(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x4013A8: distance(vector*, vector*) (in /home/javi/practica1/p1)
==4153== by 0x401A8D: main (in /home/javi/practica1/p1)
==4153==
179.780869
normalize v3
==4153== Invalid read of size 4
==4153== at 0x400EA5: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x400F3F: normalize(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401C77: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid read of size 4
==4153== at 0x400EBD: norm(vector*) (in /home/javi/practica1/p1)
==4153== by 0x400F3F: normalize(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401C77: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
89.393181
==4153== Invalid read of size 4
==4153== at 0x400F75: normalize(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401C77: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
==4153== Invalid write of size 4
==4153== at 0x400F7E: normalize(vector*) (in /home/javi/practica1/p1)
==4153== by 0x401C77: main (in /home/javi/practica1/p1)
==4153== Address 0x5a1a1ec is 0 bytes after a block of size 12 alloc'd
==4153== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4153== by 0x4014ED: main (in /home/javi/practica1/p1)
==4153==
[0.104035,0.0134238,0.994483]
v2 dot v3
0.117459
print v3
[0.104035,0.0134238,0.994483]
==4153==
==4153== HEAP SUMMARY:
==4153== in use at exit: 44 bytes in 3 blocks
==4153== total heap usage: 14 allocs, 11 frees, 204 bytes allocated
==4153==
==4153== LEAK SUMMARY:
==4153== definitely lost: 32 bytes in 2 blocks
==4153== indirectly lost: 12 bytes in 1 blocks
==4153== possibly lost: 0 bytes in 0 blocks
==4153== still reachable: 0 bytes in 0 blocks
==4153== suppressed: 0 bytes in 0 blocks
==4153== Rerun with --leak-check=full to see details of leaked memory
==4153==
==4153== For counts of detected and suppressed errors, rerun with: -v
==4153== ERROR SUMMARY: 22 errors from 18 contexts (suppressed: 2 from 2)
el código es este:
Código:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_NUMV 5
#define MAX_LONG 4000
/*********************
* 1. STRUCTS *
*********************/
typedef struct{
float* data;
int size;
} vector;
/***********************
* 2. FUNCTIONS *
***********************/
//Metodos Basicos: 20% de la nota
vector* create_vector(int n, float* data);
void destroy_vector(vector* v);
void print(vector* v);
//Metodos Intermedios: 40% de la nota
float dot(vector* v1, vector* v2);
float norm(vector* v);
void normalize(vector* v);
//Metodos Avanzados: 40% de la nota
vector* add(vector* v1, vector* v2);
vector* sub(vector* v1, vector* v2);
void incr(vector* source, vector* other);
void decr(vector* source, vector* other);
float distance(vector* v1, vector* v2);
//Extra
vector* resize(vector* x, vector* y);
// Crea el vector
vector* create_vector(int n, float* data)
{
vector* v = (vector*) malloc( sizeof(vector) );
v->data = data;
v->size = n;
return v;
}
// Borra el vector
void destroy_vector(vector* v)
{
free(v->data);
v->data=NULL;
free(v);
v=NULL;
}
// Retorna el vector més petit redimensionat.
// Obté per entrada dos punters a vectors dels quals un d'ells s'ha de redimensionar.
// Les dimensions que difereixin del vector mes gran seran afegides al vector mes petit amb un valor = 0.
vector* resize(vector* x, vector* y)
{
vector* v_resized; //Vector retornat redimensionat
int i=0;
if (x->size > y->size) //Si X te mes dimensions
{
v_resized = create_vector(x->size, y->data); //Crea un vector amb les dimensions de X y la data de Y
for (i=y->size; i<x->size; i++){ //Les dimensions restants son igualades a zero
v_resized->data[i] = 0;
}
}
else if (x->size < y->size) //Si Y te mes dimensions
{
v_resized = create_vector(y->size, x->data);
for (i=x->size; i<y->size; i++){
v_resized->data[i] = 0;
}
}
return v_resized;
}
// Imprimeix el vector per pantalla
void print(vector* v)
{
fprintf( stdout, "[" );
for (int i=0; i< v->size-1; ++i){
fprintf( stdout, "%g,", v->data[i] );
}
fprintf(stdout, "%g]\n", v->data[ v->size-1]);
}
// Retorna el producte escalar
float dot(vector* v1, vector* v2)
{
vector* v_min;
int i=0;
float suma=0;
if (v1->size >= v2->size){ //Per tenir poder comparar les dimensions dels vectors dentrada es busca quin
v_min = v2; //es el vector de menys dimensions.
}else{ //Considerant les dimensions restants com 0 el producte escalar d'elles dona 0
v_min = v1; //i per tant nomes cal sumar fins a min->size.
}
while (i <= v_min->size){
suma += (v1->data[i]*v2->data[i]);
i++;
}
printf("%f\n",suma);
//free(v_min);
v_min=NULL;
//free(v_min);
return suma;
}
// Retorna la norma del vector d'entrada
float norm(vector* v)
{
int i=0;
float norma=0;
while (i <= v->size){
norma += v->data[i]*v->data[i]; //Va fent la suma de cada component del vector elevat al quadrat
i++;
}
norma = sqrt(norma); //Arrel quadrada del total
printf("%f\n", norma);
return norma;
}
// Normalitza el vector d'entrada
void normalize(vector* v)
{
int i=0;
float norma = norm(v);
while (i <= v->size){
v->data[i] = v->data[i]/norma; //Cada component es substitueix per el seu valor dividit per la norma
i++;
}
print(v);
}
// Suma de vectors. Mostra el resultat, guardat al vector Source, per pantalla.
void incr(vector* source, vector* other)
{
int i=0;
if (source->size > other->size){ //Trobar incoherencies en les dimensions
other = resize(source, other); //Retorna el vector mes petit (other) redimensionat
}else if (source->size < other->size){
source = resize(source, other); //Retorna el vector mes petit (source) redimensionat
}
while (i <= source->size){
source->data[i] += other->data[i];
i++;
}
print(source);
}
// Resta de vectors. Mostra el resultat, guardat al vector Source, per pantalla.
void decr(vector* source, vector* other)
{
int i=0;
if (source->size > other->size){ //Trobar incoherencies en les dimensions
other = resize(source, other); //Retorna el vector mes petit (other) redimensionat
}else if (source->size < other->size){
source = resize(source, other); //Retorna el vector mes petit (source) redimensionat
}
while (i <= source->size){
source->data[i] -= other->data[i];
i++;
}
print(source);
}
// Suma de vectors, mostra el resultat per pantalla
vector* add(vector* v1, vector* v2)
{
int i=0;
if (v1->size > v2->size){ //Trobar incoherencies en les dimensions
v2 = resize(v1,v2); //Retorna el vector mes petit (other) redimensionat
}else if (v1->size < v2->size){
v1 = resize(v1,v2);
}
float *auxdata=(float*) malloc(v1->size*sizeof(float));
for(i=0;i<v1->size;i++)
{
auxdata[i] = v1->data[i]+v2->data[i];
}
vector *x=create_vector(v1->size,auxdata);
auxdata=NULL;
free(auxdata);
return x;
}
// Resta vectors, mostra el resultat per pantalla
vector* sub(vector* v1, vector* v2)
{
int i=0;
if (v1->size > v2->size){ //Trobar incoherencies en les dimensions
v2 = resize(v1,v2); //Retorna el vector mes petit redimensionat
}else if (v1->size < v2->size){
v1 = resize(v1,v2);
}
float *auxdata=(float*) malloc(v1->size*sizeof(float));
for(i=0;i<v1->size;i++){
auxdata[i] = v1->data[i]-v2->data[i];
}
vector *x=create_vector(v1->size,auxdata);
auxdata=NULL;
free(auxdata);
return x;
}
// Retorna la distancia entre dos vectors
float distance(vector* v1, vector* v2){
return norm(sub(v1,v2));
}
/******************
* 3. MAIN *
******************/
int main() {
char snvector[MAX_NUMV]; //llegir numero de vectors
int num_vectors;
vector *v=NULL;
fgets(snvector,MAX_NUMV,stdin);
num_vectors = atoi(snvector);
//printf("%d", num_vectors);//comprovar nombre vectors
vector** llista_vectors = (vector **) malloc( num_vectors*sizeof(vector*) ); //Crear un arrai de punters a vector
char copia_linea[MAX_LONG+1];
char* linea=NULL;
for(int i=0; i<num_vectors; ++i){ //Copiar contingut vector
linea = fgets(copia_linea,MAX_LONG,stdin);
int num_char = strlen(copia_linea);
int num_comas=0;
for (int j=0; j<num_char; ++j){ //Calcular # dimensions vector
if (copia_linea[j] == ',') ++num_comas;
}
int num_floats = num_comas+1;
float* data = (float*) malloc(num_floats*sizeof(float)); //Reservar espai pel # floats del vector
for (int k=0; k<num_floats; ++k){ //Copiar els floats al vector
char c;
float f;
int contador;
sscanf(linea,"%c%f%n",&c,&f,&contador);
data[k] = f;
linea = linea+contador;
//printf("%d",linea); //Per comprovar comportament de %n
}
v = create_vector(num_floats,data);
//data=NULL;
//free(data);
llista_vectors[i]= v;
print (llista_vectors[i]);
}
//Variables per les operacions
char pl;
int vector1=0;
int vector2=0;
char vaux;
char cad_dot[4]="dot";
char cad_print[6]="print";
char deinno[5]="dein";
char cad_distance[9]="distance";
char cad_normalize[10]="normalize";
int lineas=0;
while (!feof(stdin))
{
if(fgetc(stdin) == EOF)
{
break;
}
linea=fgets(copia_linea,MAX_LONG,stdin);
lineas++;
}
rewind(stdin);
for(int i=0;i<num_vectors+1;i++)
{
linea=fgets(copia_linea,MAX_LONG,stdin);
linea=NULL;
}
for(int i=0;i<lineas;i++)
{
linea=fgets(copia_linea,MAX_LONG,stdin);
printf("\n%s",linea);
sscanf(linea,"%c",&pl);
//Operacions add, sub y dot
if(pl=='v')
{
sscanf(linea,"%c%d %c %c%d",&vaux,&vector1,&pl,&vaux,&vector2);
if(pl=='+')
{
vector *aux=NULL;
aux=add(llista_vectors[vector1-1],llista_vectors[vector2-1]);
print (aux);
free(aux->data);
free(aux);
}
else if(pl=='-')
{
vector *aux=NULL;
aux=sub(llista_vectors[vector1-1],llista_vectors[vector2-1]);
print (aux);
free(aux->data);
free(aux);
}
else
{
sscanf(linea,"%c%d %s %c%d",&vaux,&vector1,cad_dot,&vaux,&vector2);
dot(llista_vectors[vector1-1],llista_vectors[vector2-1]);
}
}
else if(pl=='d')
{
sscanf(linea,"%c%c",&pl,&pl);
//distance
if(pl=='i')
{
sscanf(linea,"%s %c%d %c%d",cad_distance,&pl,&vector1,&pl,&vector2);
distance(llista_vectors[vector1-1],llista_vectors[vector2-1]);
}
//decr
else
{
sscanf(linea,"%s %c%d %c%d",deinno,&pl,&vector1,&pl,&vector2);
decr(llista_vectors[vector1-1],llista_vectors[vector2-1]);
}
}
//incr
else if(pl=='i')
{
sscanf(linea,"%s %c%d %c%d",deinno,&pl,&vector1,&pl,&vector2);
incr(llista_vectors[vector1-1],llista_vectors[vector2-1]);
}
else if(pl=='n')
{
sscanf(linea,"%c%c%c%c%c",&pl,&pl,&pl,&pl,&pl);
if(pl=='a')
{ //normalize
sscanf(linea,"%s %c%d",cad_normalize,&pl,&vector1);
normalize(llista_vectors[vector1-1]);
}
else
{ //norm
sscanf(linea,"%s %c%d",deinno,&pl,&vector1);
norm(llista_vectors[vector1-1]);
}
}
else if(pl=='p')
{
sscanf(linea,"%s %c%d",cad_print,&pl,&vector1);
print(llista_vectors[vector1-1]);
}
else
{
printf("no existe orden\n");
}
//free(aux->data);
//free(aux);
linea=NULL;
}
for(int i=0;i<num_vectors;i++)
{
destroy_vector(llista_vectors[i]);
}
free(llista_vectors);
return 0;
}
Hay unas cuantas cosas comentadas de pruebas que he hecho.
y por último el .txt que le paso cuando lo ejecuto:
Código:
3
[9.3,1.2,87.9]
[1.0,1.0]
[0.0,0.0,1.0]
v1 + v2
v3 - v1
incr v3 v1
decr v1 v3
decr v1 v3
v2 dot v3
norm v3
v1 dot v2
distance v1 v3
normalize v3
v2 dot v3
print v3
Si alguien es tan amable de decirme porque dan esos errores le estaré eternamente agradecido ya que penalizan mucho aunque funcione el programa.