I'm trying to implement a program that operates on a list of generic value nodes (pointers to void). The program works as follows: Read each line of an input file that translates each line, interprets and performs a function.
Performs functions such as addition, subtraction, normalization, distance, increment, decrement ... Running with the values of the nodes that are almost floats vectors.
To compile use:
g+ +-g-Wall-Wextra-Werror-pedantic main.cpp-o metbasicos.cpp metintermedios.cpp metavanzados.cpp eda.exe and I have no problems.
By using Valgrind've managed to eliminate all potential memory leaks and errors but one that I like and I can not resist putting it.
(valgrind - tool = memcheck - leak-check = full - show-reachable = yes. / eda.exe)
that's the whole 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;
}
}
Here you have the file that contains the implementation of some basic functions and implementation of the node vector and list:
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;
}
When I launch Valgrind, it shows me the next errors:
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)
When I try to execute the program it also shows me Segmentation fault, Core dumped
Is there anyone that can help me please?
the greatest part of the variables are written in spanish, I guess that's no a problem to understand de code.
Thank you
Look at theese two lines:
char *mystring = NULL;
and
while (fgets (mystring ,100 , stdin) != NULL){
You're dereferencing a NULLpointer.
You sure you don't want e.g.
char mystring[100];
Related
i have to sort my arrays of record but when compare 2 record one of them has NULL value. At this moment my debug for C doesn't work so if someone could give me a link to show me "how to" use , cause make error when launch with "PreLaunch returned -1 exit status" and after theh "file doesn't exixt in the path"...but this was an offtopic,so..i leave my code below , maybe i'm wrong with the usage of pointers to function cause i tried to print every call of the function " compare" and show me numeber more time that i aspected.
Main:
#include "ordered_array.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define START_CAPACITY_RECORD 10
typedef struct {
int id;
char* field1;
int field2;
float field3;
}Record;
int compare_record_int(void* ele1, void* ele2){
if(ele1 == NULL){
fprintf(stderr,"precedes_record_int_field: the first parameter is a null pointer");
exit(EXIT_FAILURE);
}
if(ele2 == NULL){
fprintf(stderr,"precedes_record_int_field: the second parameter is a null pointer");
exit(EXIT_FAILURE);
}
Record *A = (Record*)ele1;printf("\n\nele1: %d",A->id);
Record *B = (Record*)ele2;printf("\nele2: %d\n",B->id);
if(A->id < B->id) return 1;
else if(A->id > B->id)return 2;
return 0;
}
int GetRecord(char* file_name,Record* A){
FILE *fd = fopen(file_name,"rt");int i=0;
char* st=(char*)malloc(100*sizeof(char*));
if(fd == NULL){
printf("GetRecord:path file doesn't exist");
exit(EXIT_FAILURE);
};
while(!feof(fd)){
fscanf(fd,"%s\n",st);
A[i].id=atoi(strtok(st, ";"));
A[i].field1 = strdup(strtok(NULL, ";"));
A[i].field2 = atoi(strtok(NULL, ";"));
A[i].field3 = atof(strtok(NULL, ";"));
i++;
}
fclose(fd);
return i;
}
void print_record(void* record){
Record *B = (Record*)record;
printf("\nValore %d field1 %s field2 %i field3 %f ",B->id,B->field1,B->field2,B->field3);
}
int main(int argc,char* argv[]){
OrderedArray* b = ordered_array_create();
Record* A = (Record*)malloc(START_CAPACITY_RECORD*sizeof(Record));
int dim = GetRecord("TEST.csv",A);
for(int i = 0; i<dim;i++){
ordered_array_add(b,&A[i]);
}
ordered_array_print(b,print_record);
ordered_array_sort_by(b,compare_record_int);
ordered_array_print(b,print_record);
ordered_array_free(b);
free(A);
}
Library(only the part with the sort methods,for others ask me to edit in the comment):
void ordered_array_sort_by(OrderedArray * a, int (*compare)(void*,void*)){
if(a== NULL){
fprintf(stderr,"ordered_array_sort_by: ordered_array parameter cannot be NULL");
exit(EXIT_FAILURE);
}
if(compare == NULL){
fprintf(stderr,"ordered_array_sort_by: function parameter cannot be NULL");
exit(EXIT_FAILURE);
}
a->compare = compare;
a->array = array_merge_binary_insertion(a);
}
void** array_merge_binary_insertion(OrderedArray *a){
if (ordered_array_size(a) == 1)return a->array;
int m = ordered_array_size(a) / 2;
OrderedArray *B = ordered_array_create(m);
for(int i=0;i<m;i++)ordered_array_add(B,a->array[i]);
OrderedArray *C = ordered_array_create(m);
for(int i=m;i<ordered_array_size(a);i++)ordered_array_add(C,a->array[i]);
if (m <= 10){
B->array = array_binary_insertion(B->array, ordered_array_size(B),a->compare);
C->array = array_binary_insertion(C->array, ordered_array_size(C),a->compare);
}else{
B->array = array_merge_binary_insertion(B);
C->array = array_merge_binary_insertion(C);
}
return array_merge(B->array, C->array,a->compare);
}
void** array_merge(void** B,void** C,int (*compare)(void*,void*)){
if (B == NULL) return C;
else if (C == NULL) return B;
int dimB = sizeof(B) + 1;
int dimC = sizeof(C) + 1;
OrderedArray *X = ordered_array_create(dimB+dimC);
int x = 0, y = 0, i = 0;
while ((i < dimB) || (x < dimC)){
if((B[i]==NULL)||(C[i]==NULL))printf("\nerrore");
if ((*compare)(B[i],C[x]) == 1){
X->array[y] = B[i];
i++;
} else{
X->array[y] = C[x];
x++;
}
y++;
}
return X->array;
}
void** array_binary_insertion(void** array,int size,int (*compare)(void*,void*)){
//ricontrollare la funzione, non sistema bene
if(size == 1)return array;
int j = 0, x, y, temp;
OrderedArray *temp_array = ordered_array_create(size);
temp_array->array[0] = array[0];
for (int i = 1; i < size; i++){
temp = (int)array[i];
x = array_binary_search(temp_array->array, temp, 0, j,compare);
y = j;
while (y >= x){
temp_array->array[y + 1] = temp_array->array[y];
y--;
}
temp_array->array[x] = (void*)temp;
j++;
}
return temp_array->array;
}
int array_binary_search(void** array,int a,int l,int h,int (*compare)(void*,void*)){
if((array[l]==NULL)||((void*)a==NULL))printf("\nerrore");
if (l >= h){
if ((*compare)((void*)a,array[l]) == 2)
return l + 1;
else
return l;
}
int m = (l + h) / 2;
if ((*compare)((void*)a,array[m]) == 0)
return m + 1;
else if ((*compare)((void*)a,array[m]) == 2)
return array_binary_search(array, a, m + 1, h,compare);
else
return array_binary_search(array, a, l, m - 1,compare);
}
Meanwhile if you have other advice would be gratefully accepted.
So this program crashes and tells me "Aborted (core dumped)" but only when my decleration of "GENERATIONS" is greater than 6... I know its a pain that I've uploaded the whole code but I really cant figure out where it is other than it's after the return from "fibonacci_quasicrystal_generator(GENERATIONS, crystal);", as the printf statement just after gets printed, then the message appears. Code below:
#define GENERATIONS 5
#define OUTFILE "frequencies.txt"
#define GNUPLOT_EXE "gnuplot"
#define GNUPLOT_SCRIPT "frequencyplot.script"
static void fibonacci_quasicrystal_generator(int generations, char * chain);
static int plot();
int main()
{
double k = 1.0, m_a = 100.0, m_b = 1.0, m = 0.0;
char * crystal = malloc(2);
//strcopy(crystal, "A"); //gsl_vector * y_vector = gsl_vector_calloc(CHAIN_LENGTH);
fibonacci_quasicrystal_generator(GENERATIONS, crystal);
if (crystal == NULL){
printf("Crystal write failed.");
exit(0);
}
int chain_length = strlen(crystal);
printf("%i member Crystal generated, after %i generations.\n", chain_length, GENERATIONS);
gsl_matrix * a_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix * b_matrix = gsl_matrix_calloc(chain_length, chain_length);
gsl_matrix_set_identity(b_matrix);
gsl_vector * eigenvalues_vector = gsl_vector_calloc(chain_length);
for (int i = 0; i < chain_length; ++i){
if (crystal[i] == 'A'){
m = m_a;
} else {
m = m_b;
}
for (int j = 0; j < chain_length; ++j){
if ((i == j) && (i != 0 && i != chain_length)){
gsl_matrix_set(a_matrix, i, j,(2*k)/m);
}
else if (i == j-1){
gsl_matrix_set(a_matrix, i, j,(-1)*(k/m));
}
else if (i == j+1){
gsl_matrix_set(a_matrix, i ,j, (-1)*(k/m));
}
}
}
gsl_eigen_gensymm_workspace * workspace = gsl_eigen_gensymm_alloc(chain_length);
gsl_eigen_gensymm(a_matrix, b_matrix, eigenvalues_vector, workspace);
gsl_eigen_gensymm_free(workspace);
free(crystal);
gsl_matrix_free(a_matrix);
gsl_matrix_free(b_matrix);
gsl_sort_vector(eigenvalues_vector);
FILE * outfile = fopen(OUTFILE, "w");
for (int i = 0; i < chain_length; ++i){
fprintf(outfile, "%e \t%i \r\n", pow(gsl_vector_get(eigenvalues_vector, i),2), i);
}
fclose(outfile);
gsl_vector_free(eigenvalues_vector);
plot();
return 0;
}
static void fibonacci_quasicrystal_generator(int generations, char * chain){
printf("generating fibonacci quasicrystal...\n");
int i;
i = 0;
char * chain_1 = malloc(2), * chain_2 = malloc(2), * tmp = malloc(2);
strcpy(chain_1, "B");
strcpy(chain_2, "A");
size_t chain_1_size = strlen(chain_1) + 1, chain_2_size = strlen(chain_2) + 1;
if (generations == 1){
chain = realloc(chain, chain_1_size);
snprintf(chain, chain_1_size, "%s", chain_1);
}
else if (generations == 2){
chain = realloc(chain, chain_2_size);
snprintf(chain, chain_2_size, "%s", chain_2);
}
else if (generations > 2){
size_t chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
char * chain_3 = malloc(chain_3_size);
printf("%i\n", generations);
for (i = 0; i < generations - 1; ++i){
printf("%i\n", i);
snprintf(chain_3, chain_3_size, "%s%s", chain_1, chain_2);
chain_1_size = chain_2_size;
chain_2_size = chain_3_size;
if ((tmp = realloc(chain_1, chain_1_size)) != NULL){
chain_1 = tmp;
}
if ((tmp = realloc(chain_2, chain_2_size)) != NULL){
chain_2 = tmp;
}
snprintf(chain_1, chain_1_size, "%s", chain_2);
snprintf(chain_2, chain_2_size, "%s", chain_3);
if (i < generations - 2){
chain_3_size = strlen(chain_1) + strlen(chain_2) + 1;
if ((tmp = realloc(chain_3, chain_3_size)) != NULL){
chain_3 = tmp;
} else {
printf("oops!\n");
exit(1);
}
}
}
chain = realloc(chain, chain_3_size);
snprintf(chain, chain_3_size, "%s", chain_3);
free(chain_3);
}
free(chain_1);
free(chain_2);
}
static int plot(){
char command[PATH_MAX];
snprintf(command, sizeof(command), "%s %s", GNUPLOT_EXE, GNUPLOT_SCRIPT);
system(command);
return 0;
}
The problem is that char *chain into fibonacci_quasicrystal_generator function has local scope: the function does not modify the crystal pointer of main, so that pointer is left with 2 bytes.
You can change the function to
static char *fibonacci_quasicrystal_generator(int generations, char * chain)
{
// YOUR STUFF
return chain;
}
And call it from main using
crystal = fibonacci_quasicrystal_generator(GENERATIONS, crystal);
You can achieve the same using a double pointer so
static void ibonacci_quasicrystal_generator(int generations, char ** chain)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
First time posting a question on stack overflow so be nice.
I'm trying to write a program for school. This program is suppose to take a data set and turn it into a maze. The error I'm getting is a segmentation fault in putty but not in the IDE I'm using. Not sure what to do or how to handle it. I tried putting printf statements everywhere but none of them really show up doesnt make sense. Maybe because the functions themselves cause the fault not sure though what part.
//CODE BEGINS****************************************************************
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
#define FALSE 0
#define TRUE 1
typedef struct mazeStruct
{
char **arr; /* allows for a dynamic 2-D maze of any size */
int xsize, ysize;
int xstart, ystart;
int xend, yend;
bool end;
} maze;
struct linkedStruct
{
int x;
int y;
bool Unvisited;
struct linkedStruct* next;
};
typedef struct linkedStruct linked;
typedef linked* linkedPtr;
void push(linkedPtr* hd, int Xval, int Yval)
{
linkedPtr ptr = (linkedPtr) malloc(sizeof(linked));
ptr->x = Xval;
ptr->y = Yval;
ptr->Unvisited = FALSE;
ptr->next = *hd;
*hd = ptr;
}
int isEmpty(linkedPtr hd)
{
if (hd == NULL)
return TRUE;
else
return FALSE;
}
int top(linkedPtr hd)
{
return (hd->x && hd->y);
}
void pop(linkedPtr* hd)
{
linkedPtr ptr = (linkedPtr) malloc(sizeof(linked));
ptr->x = NULL;
ptr->y = NULL;
ptr->Unvisited = TRUE;
ptr->next = *hd;
*hd = ptr;
free(ptr);
}
int main(int argc, char **argv)
{
maze m1;
linkedPtr head = NULL;
int xpos, ypos;
int i, j;
m1.end = FALSE;
FILE *src;
//FILE *src = fopen ("mazeData1.txt",'r');
/* verify the proper number of command line arguments were given */
if (argc != 2)
{
printf("Usage: %s <input file name>\n", argv[0]);
exit(-1);
}
/* Try to open the input file. */
if ((src = fopen(argv[1], "r")) == NULL)
{
printf("Can't open input file: %s", argv[1]);
printf("Standard Error.\n");
exit(-1);
}
/* read in the size, starting and ending positions in the maze */
fscanf(src, "%d %d", &m1.xsize, &m1.ysize);
if (m1.xsize < 1 || m1.ysize < 1)
{
printf("Size has to be 1 or above.\n");
fscanf(src, "%d %d", &m1.xsize, &m1.ysize);
}
fscanf(src, "%d %d", &m1.xstart, &m1.ystart);
if (m1.xstart > m1.xsize || m1.ystart > m1.ysize || m1.xstart < 1
|| m1.ystart < 1)
{
printf("The start has to be within the maze.\n");
fscanf(src, "%d %d", &m1.xstart, &m1.ystart);
}
fscanf(src, "%d %d", &m1.xend, &m1.yend);
if (m1.xend > m1.xsize || m1.yend > m1.ysize || m1.xend < 1 || m1.yend < 1)
{
printf("The end has to be within the maze.\n");
fscanf(src, "%d %d", &m1.xend, &m1.yend);
}
if (m1.xend == NULL || m1.yend == NULL)
{
printf("Error: Need at least three lines of input");
exit(-1);
}
/* print them out to verify the input */
printf("size: %d, %d\n", m1.xsize, m1.ysize);
printf("start: %d, %d\n", m1.xstart, m1.ystart);
printf("end: %d, %d\n", m1.xend, m1.yend);
/* allocate the maze */
m1.arr = (char **) malloc(sizeof(char *) * (m1.xsize + 2));
for (i = 0; i < m1.xsize + 2; i++)
m1.arr[i] = (char *) malloc(sizeof(char) * (m1.ysize + 2));
/* initialize the maze to empty */
for (i = 0; i < m1.xsize + 2; i++)
for (j = 0; j < m1.ysize + 2; j++)
m1.arr[i][j] = '.';
/* mark the borders of the maze with *'s */
for (i = 0; i < m1.xsize + 2; i++)
{
m1.arr[i][0] = '*';
m1.arr[i][m1.ysize + 1] = '*';
}
for (i = 0; i < m1.ysize + 2; i++)
{
m1.arr[0][i] = '*';
m1.arr[m1.xsize + 1][i] = '*';
}
/* mark the starting and ending positions in the maze */
m1.arr[m1.xstart][m1.ystart] = 's';
m1.arr[m1.xend][m1.yend] = 'e';
/* mark the blocked positions in the maze with *'s */
while (fscanf(src, "%d %d", &xpos, &ypos) != EOF)
{
if (xpos > m1.xsize || ypos > m1.ysize || xpos < 1 || ypos < 1
|| (xpos == m1.xstart && ypos == m1.ystart)
|| (xpos == m1.xend && ypos == m1.yend))
{
printf(
"Error: X or Y is: out of range or is on the end or is on the start\n");
continue;
}
m1.arr[xpos][ypos] = '*';
}
/* print out the initial maze */
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
printf("%c", m1.arr[i][j]);
printf("\n");
}
// THE START OF THE DEPTH FIRST SEARCH METHOD
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
{
if (m1.arr[i][j] != '*')
{
head->Unvisited = FALSE;
head->next = head->next + 1; //MAYBE
}
}
}
head->x = m1.xstart;
head->y = m1.ystart;
head->Unvisited = FALSE;
while ((isEmpty(head) == FALSE) && (m1.end == FALSE))
{
if ((m1.xend == head->x) && (m1.yend == head->y))
{
printf("The END has be found!\n");
m1.end = TRUE;
}
if ((head->x + 1 && head->y) == TRUE)
{
push(&head, head->x + 1, head->y);
}
else if ((head->x - 1 && head->y) == TRUE)
{
push(&head, head->x - 1, head->y);
}
else if ((head->x && head->y + 1) == TRUE)
{
push(&head, head->x, head->y + 1);
}
else if ((head->x && head->y) == TRUE)
{
push(&head, head->x, head->y - 1);
}
else
{
pop(head);
}
}
if (isEmpty(head) == TRUE)
{
printf("Maze has no solution");
exit(0);
}
else
{
printf("%d %d", &head);
}
printf("%d", top(head));
free(m1.arr);
m1.arr = NULL;
return 1;
}
The main problem here is that you are hiding pointer with typedef:
typedef linked* linkedPtr;
In main you are declaring
linkedPtr head = NULL;
but you never allocate/mallocate space for that variable and the first piece of code that dereference it invokes Undefined Behavior because you are dereferencing a null pointer
// THE START OF THE DEPTH FIRST SEARCH METHOD
for (i = 0; i < m1.xsize + 2; i++)
{
for (j = 0; j < m1.ysize + 2; j++)
{
if (m1.arr[i][j] != '*')
{
head->Unvisited = FALSE; <----------BOOOOOOOOOOOOOOM-------
head->next = head->next + 1;
}
}
}
Moreover you have a type mismatch calling pop function, change
pop(head);
to
pop(&head);
Well, i have done the fallowing code ( basically want i want to do is: i have a list where i have some obstacles, if x=-1, the obstacles are in an entire floor, else, they are only at one place, so i want to make each time i go through the code, that the obstacles are in that position):
void restartmatrix(parking * parklot, block * obstacles, int time) {
int x, y, z;
block * tempblock;
for (z = 0; z < parklot->depth; z++) {
for (x = 0; x < parklot->width; x++) {
for (y = 0; y < parklot->height; y++) {
(parklot - > floors[x][y][z]).percorrido = -1;
}
}
}
/*tempblock = obstacles;
while(tempblock != NULL){
if(tempblock->start = time){
if(tempblock->x != -1){
for(x=0; x < parklot->width; x++){
for(y = 0; y < parklot->height; y++){
(parklot->floors[x][y][tempblock->z]).percorrido = 1;
}
}
}else{
(parklot->floors[tempblock->x][tempblock->y][tempblock->z]).percorrido = 1;
}
}else if(tempblock->end == time && tempblock->end != 0){
if(tempblock->x != -1){
for(x=0; x < parklot->width; x++){
for(y = 0; y < parklot->height; y++){
(parklot->floors[x][y][tempblock->z]).percorrido = -1;
}
}
}else{
(parklot->floors[tempblock->x][tempblock->y][tempblock->z]).percorrido = -1;
}
}
tempblock = tempblock->next;
}*/
}
Has you can see some part of the code is commented....well, the problem is if uncomment it, the program gives me a double free or corruption error (fasttop) but i can't seem to find why, since i haven't done any free...
Any help would be appreciated
EDIT
The code where i allocate the list of obstacles is here, if it can help:
block * read_blocking_list(char * file){
FILE * fp;
char leitura[256];
char temporary;
block * head = NULL;
block * temp;
block * aux;
int start, end, x = 0, y = 0, z = 0, size;
fp = fopen(file, "r");
if(fp == NULL){
printf("Erro ao abrir o ficheiro de leitura\n");
exit(0);
}
while(fgets(leitura, 255, fp) != NULL){
temp = malloc(sizeof(block));
size = sscanf(leitura, "%c %d %d %d %d %d", &temporary, &start, &end, &x, &y, &z);
temp->start = start;
temp->end = end;
temp->next = NULL;
if(size < 5){
temp->x = -1;
temp->z = x;
}else{
temp->x = x;
temp->y = y;
temp->z = z;
}
if(head == NULL){
head = temp;
}else{
aux = head;
while(aux->next != NULL){
aux = aux->next;
}
aux->next = temp;
}
}
fclose(fp);
return head;
}
Careful of = versus ==:
if(tempblock->start = time){
should be
if(tempblock->start == time){
Also, this block of code:
if(tempblock->x != -1){
for(x=0; x < parklot->width; x++){
for(y = 0; y < parklot->height; y++){
(parklot->floors[x][y][tempblock->z]).percorrido = 1;
}
}
}else{
(parklot->floors[tempblock->x][tempblock->y[tempblock>z]).percorrido = 1;
}
Is like saying:
if(tempblock->x != -1){
/* Do some stuff here while tempblock->x is NOT -1. */
}else{
/* So in this block, tempblock->x IS EQUAL TO -1. */
(parklot->floors[tempblock->x][tempblock->y][tempblock->z]).percorrido = 1;
}
So, trying to clearly illustrate where that leaves us, we have:
if(tempblock->x != -1){
/* Do some stuff here while tempblock->x is NOT -1. */
}else{
/* So in this block, tempblock->x IS EQUAL TO -1. */
(parklot->floors[-1][tempblock->y][tempblock->z]).percorrido = 1;
}
Notice the parklot->floors[-1]. You are definitely out of bounds.
You test if tempblock-x != -1 and use tempblock->x in the else block this way:
(parklot->floors[tempblock->x][tempblock->y][tempblock->z]).percorrido = 1;
Thus you are most likely indexing out of bounds. Check your logic.
UPDATE: Memory leaks killed, now I need to know how can I initialize this statement:
vector *addorsub = (vector*)malloc(sizeof(*addorsub));
This is what I get from valgrind:
gerasg#gerasg-iMac:~/Escritorio/valgrind/vg$ valgrind --tool=memcheck --leak-check=full --track-origins=yes ./eda.exe
==6129== Memcheck, a memory error detector
==6129== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6129== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6129== Command: ./eda.exe
==6129==
==6129== Conditional jump or move depends on uninitialised value(s)
==6129== at 0x4C2A7E4: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6129== by 0x4015E7: destroy_vector(vector*) (metbasicos.c:17)
==6129== by 0x4014E2: main (main.c:175)
==6129== Uninitialised value was created by a heap allocation
==6129== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6129== by 0x400D59: main (main.c:87)
==6129==
==6129==
==6129== HEAP SUMMARY:
==6129== in use at exit: 0 bytes in 0 blocks
==6129== total heap usage: 2 allocs, 2 frees, 16 bytes allocated
==6129==
==6129== All heap blocks were freed -- no leaks are possible
==6129==
==6129== For counts of detected and suppressed errors, rerun with: -v
==6129== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
And this is the main program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "metbasicos.h"
#include "metintermedios.h"
#include "metavanzados.h"
//NumsVector, funcion que nos devuelve el numero de "numeros" que hay en cada vector del .txt,
//es decir, los n floats por cada vector
int NumsVector(char *linea, int size){
int numsvector = 1; //Inicializamos a 1 ya que no podemos suponer valor maximo segun enunciado, pero si minimo >= 1
int n;
for(n = 2; n<= size; n++){ //como ya suponemos que el primer valor despues del corchete es un numero y ya lo hemos contado, empezamos en 2
if (linea[n] != '[' && linea[n] != ']'){
if(linea[n] == 44){
numsvector = numsvector + 1;
}
}
}
return numsvector;
}
int main(){
int n =0, i = 0;
scanf("%d\n", &n);
vector **v = (vector **)malloc(sizeof(vector*) * n);
for(i = 0; i<n; ++i) {
char *line = NULL, ch;
int it = 0 ;
line = (char*) malloc (2*sizeof(char)) ;
*line = '\0' ;
while((ch=getchar()) != '\n')
{
*(line+it) = ch ;
it++ ;
line = (char*) realloc(line, (2*sizeof(char)) + it ) ;
}
*(line+it) = '\0';
int read = strlen(line);
int numsvector = NumsVector(line, read);
float* nfloat; //sabemos el tamanyo del vector que hemos leido, creamos array de floats y lo llenamos de los floats
//empieza el proceso para obtener los floats a partir de string de chars
nfloat = (float*)malloc(numsvector*sizeof(float));
int j = 0;
line[strlen(line)] = ','; /* Replaces the end ] with a , */
char *p = line + 1; /* creates a new pointer, pointing after the first [ in the original string */
do
{
sscanf(p, "%f,", &nfloat[j]); /* grabs up to the next comma as a float */
while (*(p++) != ',') ; /* moves pointer forward to next comma */
}
while (++j < numsvector); /* stops when you've got the expected number */
v[i] = create_vector(numsvector, nfloat);//conseguimos almacenar el contenido del string en un vector del tipo float (nfloat)
int aux;
for(aux = 0; aux<numsvector; ++aux){ //test de que cada elemento se ha guardado bien y printa todos los elementos ok
printf("V[%d]->data[%d] = : %.1f\n", i, aux, v[i]->data[aux]); //test de que la memoria se almacena bien, luego se borra
}
free(line);
free(nfloat);
}
char mystring [21];
char str[10], charv1[6], charv2[6];
int operation = 0;
char simbol[4]; /* Can be +, - and dot */
mystring[0] = str[0] = charv1[0] = charv2[0] = simbol[0] = 'a';
for(i = 0; i<21; i++){
mystring[i] = 'a';
}
for(i = 0; i<6; i++)
{
charv1[i] = 'a';
charv2[i] = 'a';
}
for (i = 0; i < 10; i++)
{
str[i] = 'a';
}
for (i = 0; i < 4; i++)
{
simbol[i] = 'a';
}
vector *addorsub = (vector*)malloc(sizeof(*addorsub));
fgets (mystring , 21 , stdin);
do {
sscanf (mystring,"%s",str);
int res = strlen (str);
//int res = strncmp(str, "incr", 10);
if(mystring[0] == 'p') operation = 1;
else if(mystring[0] == 'i') operation = 2;
else if(mystring[0] == 'd' && mystring[1] == 'i') operation = 4;
else if(mystring[0] == 'd' && mystring[1] == 'e') operation = 5;
else if(res == 9) operation = 6;
else if(res == 4 && mystring[0] == 'n') operation = 7;
else{
sscanf (mystring,"%s %s",str, simbol);
if (simbol[0] == '+') operation = 8;
else if(simbol[0] == '-') operation = 9;
else operation = 3;
}
int v1 = 0, v2 = 0;
float returnresult = 0.0;
switch(operation)
{
case 1 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
printf("PRINT: %d\n", v1);
print(v[v1-1]);
break;
case 2 :
sscanf (mystring,"%s %s %s",str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
printf("INCREASE: %d %d\n", v1, v2);
incr(v[v1-1], v[v2-1]);
break;
case 3 :
sscanf (mystring,"%s %s %s",charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
returnresult = dot(v[v1-1], v[v2-1]);
printf("DOT: %d %d\n", v1, v2);
printf("%f\n", returnresult);
break;
case 4 :
sscanf (mystring,"%s %s %s", str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
returnresult = distance(v[v1-1], v[v2-1]);
printf("%f\n", returnresult);
break;
case 5 :
sscanf (mystring,"%s %s %s",str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
decr(v[v1-1], v[v2-1]);
break;
case 6 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
normalize(v[v1-1]);
break;
case 7 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
returnresult = norm(v[v1-1]);
printf("%f\n", returnresult);
break;
case 8 : //suma
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = add(v[v1-1], v[v2-1]);
printf("SUMA: %d %d\n", v1, v2);
print(addorsub);
break;
case 9 :
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = sub(v[v1-1], v[v2-1]);
printf("resta: %d %d\n", v1, v2);
print(addorsub);
break;
default :
printf("operation value is: %d\n", operation);
break;
}
operation = 0;
} while (fgets (mystring , 21 , stdin) != NULL);
for (i = 0; i < n; ++i)
{
destroy_vector(v[i]);
}
free(v);
}
I checked all malloc and frees, but I think I'm leaving anything ...
any ideas? thank you very much.
EDIT:
Input example (int a .txt file as stdin):
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
distance v1 v3
normalize v3
print v3
Struct:
typedef struct {
float* data;
int size;
} vector;
metbasicos.c:
#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* Metodos Básicos */
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;
}
void destroy_vector(vector* v){
free(v->data);
free(v);
}
void print(vector* v){
int size = v->size, i;
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]);
}
}
metintermedios.c:
#include "metintermedios.h"
#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* Metodos Intermedios */
float dotDiferentSizes(vector* v1, vector* v2, int smax, int smin){
float prod = 0.0;
int i;
for(i = 0; i < smin; i++){
prod = prod + (v1->data[i])*(v2->data[i]); // += means add to product
}
for(i = smin; i < smax; i++){
prod += (v1->data[i])*0; // += means add to product
}
return prod;
}
float dot(vector* v1, vector* v2){
int smax = (v1->size), smin = 0;
int v1size = smax;
int v2size = (v2->size);
float product = 0.0;
if (v2size > smax) {
smax = v2size; //max_size checking
smin = v1size; //min_size checking
}
else if (v2size < smax){
smin = v2->size;
}
else {
if(v1size == v2size){
smin = smax;
}
}
// compute
if(smax == smin){
int i;
for(i = 0; i < smin; i++){
product += (v1->data[i])*(v2->data[i]); // += means add to product
}
}
else{
if(v1size == smax && v1size!= smin){
product = dotDiferentSizes(v1,v2,smax,smin); //v1>v2
}
if(v2size == smax && v2size!= smin){
product = dotDiferentSizes(v2,v1,smax,smin); //v2>v1 OJU nomes canviem l'ordre en que posem els parametres, la funcio es identica.
}
}
return product;
}
float norm(vector* v){
int size = v->size, i;
float norm = 0.0;
for(i= 0; i < size; i++){
norm += (v->data[i])*(v->data[i]);
}
norm = sqrt( norm );
return norm;
}
void normalize(vector* v){
int size = v->size, i;
float norma = 0.0;
norma = norm(v);
for(i= 0; i< size; i++){
v->data[i] = v->data[i] / norma;
}
print(v);
}
metavanzados.c:
#include "metavanzados.h"
#include "metintermedios.h"
#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* Metodos Avanzados */
vector* add(vector* v1, vector* v2){
vector *vadd = (vector*)malloc(sizeof(*vadd));
int v1size, v2size, i;
v1size = v1->size;
int size = v1size;
v2size = v2->size;
if(v2size > v1size) {
size = v2size;
vadd = create_vector(size, v2->data);
for(i = 0; i < v1size; i++){
vadd->data[i] += v1->data[i];
}
}
else {
vadd = create_vector(size, v1->data);
for(i = 0; i < v1size; i++){
vadd->data[i] += v2->data[i];
}
}
return(vadd);
destroy_vector(vadd);
}
vector* sub(vector* v1, vector* v2){
vector *vsub = (vector*)malloc(sizeof(*vsub));
int v1size, v2size, i;
v1size = v1->size;
int size = v1size;
v2size = v2->size;
if(v2size > v1size) {
size = v2size;
vsub = create_vector(size, v2->data);
for(i = 0; i < v1size; i++){
vsub->data[i] = v1->data[i] - vsub->data[i]; /* restamos siempre v1 - v2*/
} /* en el bucle forzamos a restar v1 - v2, evitando el caso v2 - v1*/
for(i = v1size; i < size; i++){
vsub->data[i] = (v2->data[i])*(-1);
}
}
else { /* v1size >= v2size */
vsub = create_vector(size, v1->data);
for(i = 0; i < v2size; i++){
vsub->data[i] -= v2->data[i];
}
}
return(vsub);
destroy_vector(vsub);
}
void incr(vector* source, vector* other){
int smax, i, ssize = source->size, osize = other->size;
vector *vincr = (vector*)malloc(sizeof(*vincr));
if(ssize > osize) smax = ssize;
else {
if(ssize < osize) smax = osize;
else smax = ssize;
}
vincr = add(source, other);
if(ssize > osize){
for(i = 0; i < smax; i++){
source->data[i] = vincr->data[i];
}
}
else{
source->data = (float*)realloc(source->data, sizeof(float) * smax);
source->size = smax;
for(i = 0; i < smax; i++){
source->data[i] = vincr->data[i];
}
}
print(source);
destroy_vector(vincr);
}
void decr(vector* source, vector* other){
int smax, i, ssize = source->size, osize = other->size;
if(ssize > osize) smax = ssize;
else {
if(ssize < osize) smax = osize;
else smax = ssize;
}
vector *vdecr = (vector*)malloc(sizeof(*vdecr));
vdecr = sub(source, other);
if(ssize > osize){
for(i = 0; i < smax; i++){
source->data[i] = vdecr->data[i];
}
}
else{
source->data = (float*)realloc(source->data, sizeof(float) * smax);
source->size = smax;
for(i = 0; i < smax; i++){
source->data[i] = vdecr->data[i];
}
}
print(source);
destroy_vector(vdecr);
}
float distance(vector* v1, vector* v2){
int i;
float dist = 0.0;
vector *vdist = (vector*)malloc(sizeof(*vdist));
vdist = sub(v1, v2);
for(i = 0; i<= vdist->size; i++){
vdist->data[i] = (vdist->data[i])*(vdist->data[i]);
dist += vdist->data[i];
}
dist = sqrt( dist );
return dist;
destroy_vector(vdist);
}
This is all the code.
case 8 : //suma
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = add(v[v1-1], v[v2-1]);
printf("SUMA: %d %d\n", v1, v2);
print(addorsub);
break;
This is your problem. The pointer addorsub has already been malloc'd, but the add() function returns a vector pointer which is malloc'd. So the vadd vector pointer inside of the add() function is overwriting the addorsub pointer, which makes the allocated memory already in the addorsub pointer just...disappear into thin air.
The same thing happens with the sub() function. It's actually impossible to destroy the allocated memory after the return statement, so you have to destroy the memory in the pointer outside of the add() or sub() functions before you call those functions in order to preserve your memory.
So in the main() function, the incr() function, the decr() function, etc., you need to take out the memory allocation for anything that receives a pointer for add() or sub(), as well as making sure that if it's inside of a loop that you destroy any memory currently allocated before reassigning the pointer to a different address.
UPDATE: Memory leaks killed, now I need to know how can I initialize this statement:
vector *addorsub = (vector*)malloc(sizeof(*addorsub));
You won't. Just make it
vector * addorsub = NULL;
And make sure that addorsub gets a call to free() in every iteration of the loop.
The main issue is that the program is crashing before it has a chance to free the memory. A big part of the problem seems to be here:
line[strlen(line)] = ','; /* Replaces the end ] with a , */
it should be
line[strlen(line)-1] = ','; /* Replaces the end ] with a , */
There are various other memory issues as well. For example, addorsub is allocated but not freed.
In general, when using valgrind, try to start with the first error and work your way down. Looking at the end is misleading, since earlier errors can have the side-effect of causing the later ones.