currently doing a project with a board with several routines:
#include <xc.h>
#include "config.h"
#define TRUE 1
#define FALSE 0
#define SW1 PORTBbits.RB4
#define SW2 PORTBbits.RB5
#define PB3 PORTCbits.RC3 //for testing
#define PB2 PORTDbits.RD1
#define PB7 PORTCbits.RC7
#define PB8 PORTCbits.RC6
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void ReadLight(void);
void ReadTemperature(void);
void ReadSoilMoisture(void);
void MessageDoze(void);
void MessageSleep(void);
void lcdClear(void);
void initLCD(void);
void initSysInt(void);
void initSysTimer(void);
void pwrMgmt(void);
void initPWM(void);
unsigned char detPB3(void); //for testing
unsigned char detPB2(void);
unsigned char detPB7(void);
unsigned char detPB8(void);
void main(void) {
initSysInt();
initSysPins();
initSysTimer();
CPUDOZE = 0;
while(TRUE){
if(SW1 == 1 && SW2 == 0){
ReadTemperature();
}
else if (SW1 == 0 && SW2 == 1){
ReadLight();
}
else if (SW1 == 1 && SW2 == 1){
ReadSoilMoisture();
}
else {
lcdClear();
}
pwrMgmt();
//pwrMgmt1();
}
}
void pwrMgmt(void){
if(PB2 == 0){
lcdClear();
ROI = 1;
MessageSleep();
SLEEP();
__delay_ms(500);
}
else if(PB7 == 0){
lcdClear();
MessageDoze();
DOZEN= 1;
ROI = 1;
}
}
unsigned char detPB3(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB3 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB3 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB3 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB2(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB2 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB2 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB2 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB7(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB7 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB7 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB7 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB8(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB8 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB8 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB8 == 0);//wait for sw1 to be released
}
}
return detect;
}
The only problem is that my DC motor still runs on its own despite only being called inside my soil moisture function. the other functions just use LCD and LED and work fine. I've tried working around this by putting MOTOR = 0; inside my main but that doesn't do anything.
EDIT: Works on its own before integration with the rest of my codes.
ReadSoilMoisture():
#include <xc.h>
#include "config.h"
#define lcd_Clear 0b00000001
#define LCD_DATA PORTD
#define LCD_RS PORTEbits.RE1 //RS signal for LCD
#define LCD_E PORTEbits.RE0 // E signal for LCD
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void lcdWriteData(char);
void lcdWriteCtrl(char);
void lcdWriteMessage(char message[], unsigned char row);
void lcdSetPos(unsigned char row, unsigned char col);
void initPWM(void);
//void Message(void);
void Message1(void);
void Message2(void);
void Message(void);
void initLCD(void);
void initADC(void);
unsigned int readPot1(void);
void ReadSoilMoisture(void) {
unsigned int raw;
unsigned char pwmCycle = 0;
// float fresult;
// char res[20];
initLCD();
initSysPins();
initPWM();
initADC();
PWM6CONbits.EN = 1;
// raw = readPot1();
int i = 0;
for(i = 0; i<=40; i++) {
raw = readPot1();
if (raw == 0 && raw <= 10)
{
PORTA = 0x00;
}
else if (raw == 11 && raw <=100)
{
PORTA = 0b00001001; //RED
MOTOR = 1;
pwmCycle = 4000;
__delay_ms(5000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 101 && raw <= 1000)
{
PORTA = 0b00010010; //YELLOW
MOTOR = 1;
pwmCycle = 1500;
__delay_ms(3000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message1();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 1001 && raw <= 1023)
{
PORTA = 0b00100100; //GREEN
MOTOR = 1;
pwmCycle = 900;
__delay_ms(800);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message2();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
}
}
void Message(void){
char message[] = "Soil Moisture";
char message1[] = "Is 55%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message1(void){
char message[] = "Soil Moisture";
char message1[] = "Is 75%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message2(void){
char message[] = "Soil Moisture";
char message1[] = "Is 95%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void initPWM(void)
{
CCPTMRS1 = PORTDbits.RD0;
PWM6CON = 0b00000000;
T2PR = 249;
PWM6DCH = 0b01111101;
PWM6DCL = 0b00000000;
T2CON = 0b11110000;
T2CLKCON = 0b00000001;
RA2PPS = 0x0E;
}
Any guess as to what I can do?
I have to write a program which reads dates and todo-s as command line arguments and puts these in a text-file (line by line).
Correct input:
./todo 13:58 todo1 00:00 todo2 08:30 todo3
Wrong input:
./todo 13:58 todo1 24:00 todo2 08:30 todo3 or ./todo 13:58 todo1 todo2 00:00 08:30 todo3
Correct todolist.txt file:
13:58 - todo1
00:00 - todo2
08:30 - todo3
The code is compiled successfully, but when I run the program, I get segmentation fault:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool isValidTime(char* argv)
{
char hour[2] = {0};
char minute[2] = {0};
for (unsigned int i = 0; argv[i] != ':'; i++) {
hour[i] = argv[i];
}
int hourNum = atoi(hour);
if (!(hourNum >= 0 && hourNum < 24)) {
return false;
}
for (unsigned int i = 3; i < sizeof(*argv) / sizeof(argv[0]); i++) {
minute[i] = argv[i];
}
int minuteNum = atoi(minute);
if (!(minuteNum >= 0 && minuteNum < 60)) {
return false;
}
return true;
}
bool isValidTodo(char* argv)
{
for (unsigned int i = 0; i < sizeof(*argv) / sizeof(argv[0]); i++) {
if (!(argv[i] >= 'a' && argv[i] <= 'z')) {
return false;
}
}
return true;
}
int main(int argc, char* argv[])
{
if (argc < 3) {
printf("Incorrect input!\n");
return 1;
}
FILE* file;
file = fopen("todolist.txt", "w");
if (file == NULL) {
printf("File failed to open.\n");
return 1;
}
for (int i = 1; i < argc; i++) {
if (!(isValidTime(argv[2 * i - 1]) && isValidTodo(argv[2 * i]))) {
printf("Incorrect input!\n");
}
fprintf(file, "%s - %s\n", argv[2 * i - 1], argv[2 * i]);
}
fclose(file);
return 0;
}
Most likely it is because of this code:
for (int i = 1; i < argc; i++) {
if (!(isValidTime(argv[2 * i - 1]) && isValidTodo(argv[2 * i]))) {
printf("Incorrect input!\n");
}
fprintf(file, "%s - %s\n", argv[2 * i - 1], argv[2 * i]);
}
You are getting argc number of arguments, but then you index the array using argv[2 * i - 1]. Say you have 4 arguments - you are going to try to index element 2 * 4 - 1, that is, element 7 which would be outside the array, hence the segmentation fault.
You probably need to just remove the 2 * part, if your goal is to do something with the previous and current elements.
Another issue I see is this code:
for (unsigned int i = 0; argv[i] != ':'; i++) {
hour[i] = argv[i];
}
In case there is no : in the argument, you will loop indefinitely and will get another segmentation fault for hour[i] and argv[i].
My functions (init,draw,move and win) are not working properly. Can anyone shed some light on where I am going wrong?
init - should initialer the board and swap 1 and 2.
draw - should draw the current state of the board.
move - should move the tile if not illegal move.
win - should check the board if its in descending order.
/**
* fifteen.c
*
* Computer Science 50
* Problem Set 3
*
* Implements Game of Fifteen (generalized to d x d).
*
* Usage: fifteen d
*
* whereby the board's dimensions are to be d x d,
* where d must be in [DIM_MIN,DIM_MAX]
*
* Note that usleep is obsolete, but it offers more granularity than
* sleep and is simpler to use than nanosleep; `man usleep` for more.
*/
#
define _XOPEN_SOURCE 500
# include < cs50.h > #include < stdio.h > #include < string.h > #include <
stdlib.h > #include < unistd.h >
// constants
#define DIM_MIN 3# define DIM_MAX 9
// board
int board[DIM_MAX][DIM_MAX];
// dimensions
int d;
// prototypes
void clear(void);
void greet(void);
void init(void);
void draw(void);
bool move(int tile);
bool won(void);
void metrytoexchange(int * a, int * b);
int main(int argc, string argv[]) {
// ensure proper usage
if (argc != 2) {
printf("Usage: fifteen d\n");
return 1;
}
// ensure valid dimensions
d = atoi(argv[1]);
if (d < DIM_MIN || d > DIM_MAX) {
printf("Board must be between %i x %i and %i x %i, inclusive.\n",
DIM_MIN, DIM_MIN, DIM_MAX, DIM_MAX);
return 2;
}
// open log
FILE * file = fopen("log.txt", "w");
if (file == NULL) {
return 3;
}
// greet user with instructions
greet();
// initialize the board
init();
// accept moves until game is won
while (true) {
// clear the screen
clear();
// draw the current state of the board
draw();
// log the current state of the board (for testing)
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
fprintf(file, "%i", board[i][j]);
if (j < d - 1) {
fprintf(file, "|");
}
}
fprintf(file, "\n");
}
fflush(file);
// check for win
if (won()) {
printf("ftw!\n");
break;
}
// prompt for move
printf("Tile to move: ");
int tile = GetInt();
// quit if user inputs 0 (for testing)
if (tile == 0) {
break;
}
// log move (for testing)
fprintf(file, "%i\n", tile);
fflush(file);
// move if possible, else report illegality
if (!move(tile)) {
printf("\nIllegal move.\n");
usleep(500000);
}
// sleep thread for animation's sake
usleep(500000);
}
// close log
fclose(file);
// success
return 0;
}
/**
* Clears screen using ANSI escape sequences.
*/
void clear(void) {
printf("\033[2J");
printf("\033[%d;%dH", 0, 0);
}
/**
* Greets player.
*/
void greet(void) {
clear();
printf("WELCOME TO GAME OF FIFTEEN\n");
usleep(2000000);
}
/**
* Initializes the game's board with tiles numbered 1 through d*d - 1
* (i.e., fills 2D array with values but does not actually print them).
*/
void init(void) {
// TODO
int i, j;
int k = d * d - 1;
for (i = 0; i < d; i++) {
for (j = 0; j < d; j++) {
board[i][j] = k--;
if (k % 2 != 0) {
break;
} else {
if ((board[i][j] == 2) && (board[i][j - 1] == 1))
metrytoexchange( & board[i][j], & board[i][j - 1]);
}
}
}
}
/**
* Prints the board in its current state.
*/
void draw(void) { // TODO
int k = d * d - 1;
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
board[i][j] = k--;
if (board[i][j] == 0) {
printf("_");
} else
printf("%d \t", board[i][j]);
}
printf("\n");
}
}
void metrytoexchange(int * a, int * b) {
int temp = * a; *
a = * b; *
b = temp;
}
/**
* If tile borders empty space, moves tile and returns true, else
* returns false.
*/
bool move(int tile) {
int k = d * d - 1;
int blank_space = 0;
//dont go beyond the grid
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
if (tile < k && tile > 0 && tile == board[i][j]) {
continue;
} else {
break;
}
//iterate to check the position of of blank tile;left to right up and down if not return false
if (board[i - 1][j] != blank_space || board[i][j - 1] !=
blank_space || board[i + 1][j] != blank_space || board[i][j +
1
] != blank_space) {
return false;
}
//else swap tile with blank_space
else {
metrytoexchange( & tile, & blank_space);
return true;
}
}
}
return false;
}
/**
* Returns true if game is won (i.e., board is in winning configuration),
* else false.
*/
bool won(void) {
// TODO
// creat a variable that increases as the loop condition increases.let it start from 1 increasing
int win_board[d][d];
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
if (win_board[i][j] == board[i][j]) {
return true;
} else {
return false;
}
}
}
return false;
}
I´m trying to adapt a algorithm from matlab.
My algorithm:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <cwp.h>
#define MAX_LINES 225000
#define MAX_SAMPLE 2500
#define LMAX 200000
#define LFILT 128
#define TamConv 2580
#define LENGTH_(x) (sizeof(x)/sizeof(x[0]))
int
main(argc, argv)
int argc;
char **argv;
{
FILE *fp;
float data[MAX_LINES], samples[MAX_SAMPLE], mexh[81], values;
float j, pi, mean_atraso, passo, total_passo;
double escala[] = {1, 2, 4, 8};
size_t escala_len,k,l;
int i,m,n;
long unsigned int tex;
float convol[TamConv],aux1[TamConv],aux2[TamConv];
pi = M_PI;
/*
Leitura dos Dados
*/
/*
if (argv[1] == NULL) {
perror("Sem arquivo de texto!");
return 1;
} */
fp = fopen("exames.txt", "r");
if (fp == NULL) {
perror("Arquivo vazio!");
return 1;
}
while((fscanf(fp, "%lf", &values) && (i < MAX_LINES))) {
data[i] = values;
if (i <= MAX_SAMPLE) {
samples[i] = values;
mean_atraso += values;
}
i++;
}
fclose(fp);
printf("DATA: %lu \n", LENGTH_(data)); // Tamanho do arquivo
/*
Calcula a tal media mean_atraso
*/
mean_atraso /= MAX_SAMPLE;
for (i=0; i<=MAX_SAMPLE; i++) {
samples[i] -= mean_atraso;
}
/*
Chapéu Mexicano
*/
escala_len = LENGTH_(escala);
printf("%zu \n", escala_len);
i=0;
while (i < escala_len) {
/*
Chapéu Mexicano
*/
passo = (float)1/escala[i];
total_passo = 10/passo;
for(j=-5, k=0; j<5, k<total_passo; j+=passo,k++) {
mexh[k] = 2.1741*(1/sqrt(2*pi)*(1-pow(j,2))*exp(-pow(j,2)/(2)));
}
/*
Convolution
*/
// conv(total_passo,mexh[0],mexh,MAX_SAMPLE,data[0],data,MAX_SAMPLE+total_passo,0,convol);
//
for(k=0; k<(MAX_SAMPLE+total_passo); k++) {
if (k<MAX_SAMPLE)
aux1[k]=data[k];
else
aux1[k]=0;
if (k<total_passo)
aux2[k]=mexh[k];
else
aux2[k]=0;
}
for(l=0;l<(2500+total_passo); l++) {
convol[l]=0;
convol[l] =convol[l]+ (aux1[l] * aux2[l]);
}
//derivada de primeira ordem
for (i=1; i<MAX_SAMPLE; i++)
convol[i-1]=convol[i]-convol[i-1];
/*
Hilbert
*/
hilbert(MAX_SAMPLE+total_passo, convol [],aux1 [] );
i++;
}
return 0;
}
I´d like to implement convolution and hilbert from this lib cwplib
I try to implement convolution by this algorithm above but the results differ from Matlab.
If not, how can I implement Hilbert for another way or the convolution?
How can I do? Thanks any help.
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.