0
int get_rates(Date start_at, Date end_at,unsigned n_currencies, char *currencies[], Rate *result){
    char link[1024];
    char * simbolos=envirgular(currencies,n_currencies);
    char * linkp=link;
    snprintf(link, sizeof(link),  "https://api.exchangeratesapi.io/history?start_at=%d-%d-%d&end_at=%d-%d-%d&symbols=%s"
    ,start_at.year,start_at.month,start_at.day,end_at.year,end_at.month,end_at.day,simbolos);
    start_at.day++;
    size_t datasize;
    char *a=http_get_data(linkp,&datasize);
    int numerodedias=getnumberofdays(a);
    result=realloc(result,numerodedias*sizeof(Rate));
    Date datas[numerodedias];
    char * info=strstr(a,"rates");
    char * data=malloc(10*sizeof(char));
    char * year=malloc(4*sizeof(char));
    char * day_month=malloc(2*sizeof(char));
    char * value=malloc(6*sizeof(char));
    for(int j=0;j<numerodedias;j++){
        result[j].values=calloc(n_currencies,sizeof(char*));
        result[j].names=calloc(n_currencies,sizeof(char*));
        info=strstr(info,"-");
        info=info-4;
        strncpy(data,info,10);
        strncpy(year,data,4);
        datas[j].year=atoi(year);
        data=data+5;
        strncpy(day_month,data,2);
        datas[j].month=atoi(day_month);
        data=data+3;
        strncpy(day_month,data,2);
        datas[j].day=atoi(day_month);
        for(int i=0;i<n_currencies;i++){
            info=strstr(info,currencies[i]);
            info=info+5;
            strncpy(value,info,6);
            result[j].values[i]=value;
            result[j].names[i]=currencies[i];





    }
    for(int i=0;i<2;i++){
    printf("\nValor%s\nMoeda%s\n",result[j].names[i],result[j].values[i]);}
    result[j].data.day=datas[j].day;
    result[j].data.month=datas[j].month;
    result[j].data.year=datas[j].year;
    //printf("\nDia:%d-%d-%d   %s=%s    %s=%s\n",result[j].data.day,result[j].data.month,result[j].data.year,result[j].names[0],result[j].values[0],result[j].names[1],result[j].values[1]);
        }

    return 0;
}

typedef struct Data{
    int year;
    int month;
    int day;

}Date;


typedef struct SingleRate{
    Date  data;
    char **names;
    char **values;
}Rate;

Hello Stack Overflow community,I'm learning C language in my class and i was asked to make this little project that searches in a website using libcurl for some info about certain currencies and values in a determined day. I got to a point that i can continue due to this error,i've been searching on the internet for answers of the same error but i didnt seem to find where it was Would be glad if someone could explain to me what im doing wrong Thanks.

  • Also I can see trough some printf's that the problem seems to be with the values array – Joao Barata Feb 07 '19 at 17:08
  • Please make a [mcve] out of it. – Eugene Sh. Feb 07 '19 at 17:08
  • 1
    I don't see any calls to `free` or `realloc`. Or any direct buffer overflows (but that's hard to see with that wall of code). Please try to create a [**Minimal**, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve) to show us. – Some programmer dude Feb 07 '19 at 17:09
  • Ok i will try to,thank you :) – Joao Barata Feb 07 '19 at 17:10
  • @Someprogrammerdude There is `realloc`, but not `free`. – Eugene Sh. Feb 07 '19 at 17:10
  • 1
    Also, please [learn how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). And that will be much simpler with simpler code. Try to scale back and remove as much as you possible can. Test it. Then add a ***small*** piece of code, test it. Add another *small* piece of code. Test it. And so on. That will help finding problems and debugging considerable. – Some programmer dude Feb 07 '19 at 17:11
  • After using `strncpy` you must make sure that the target array is teminated with a `'\0'` to make it a proper string. – Weather Vane Feb 07 '19 at 17:12
  • @EugeneSh. Ah yes there was. And that's probably the problem here: Joao, you pass the `result` pointer ***by value***, meaning the local variable `result` is a ***copy***. Assigning to `result` will modify this local copy, and *only* this local copy. The original pointer you used when calling the function will *not* be changed by that assignment. – Some programmer dude Feb 07 '19 at 17:13
  • If _valgrind_ available in your OS use it to detect your illegal accesses and more – bruno Feb 07 '19 at 17:13
  • Why are you allocating `data,year,day_month` and _values_ ? That seems useless, just use array in stack – bruno Feb 07 '19 at 17:16
  • And there are so many other problems and flaws in your code that it would take a very long answer to list them all. To begin with you have memory leaks, you should never assign back to the pointer you pass to `realloc`, there's no null-pointer checking or error handling of any kind, or possibilities of having unterminated strings, just to list a few issues. And that's besides the one problem that was the probable cause for your crash. A *lot* of possibilities for [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Feb 07 '19 at 17:18
  • Lastly, the *only* good thing that I see in your code, is the use of `snprintf` to format the string in `link`. – Some programmer dude Feb 07 '19 at 17:23
  • @Someprogrammerdude I used malloc to allocate my result pointer in main and i did used realloc to update the result outside this fuction – Joao Barata Feb 07 '19 at 17:29
  • @WeatherVane I went on debug mode to check if all the strings were fine – Joao Barata Feb 07 '19 at 17:30
  • @JoaoBarata Please read my comment about passing `result` by value again. The result of that `realloc` is assigned to the ***local*** variable `result`. You never pass that back to the calling function. Do some research about *emulating pass by reference in C* to learn how to do it. – Some programmer dude Feb 07 '19 at 17:39
  • @JoaoBarata In short: After calling the function you show, the pointer you pass for `result` is no longer valid. You can't use it for anything at all. – Some programmer dude Feb 07 '19 at 17:40
  • @Someprogrammerdude I cant use the result to put thing's to have acess outside this function? But it seemed to work on the debbuger as i exit this function – Joao Barata Feb 07 '19 at 17:47
  • As I said, that pointer used in the call is lost. Or rather, it will still point to the *old* memory. When you try to use it in `realloc` again, or in `free`, then you will get the crash you ask about. – Some programmer dude Feb 07 '19 at 18:18

1 Answers1

0

Warning :

char * year=malloc(4*sizeof(char));
...
strncpy(year,data,4);
datas[j].year=atoi(year);

year has no place for the ending null character and it is missing in that case, atoi has an undefined behavior

Same for day_month

char * day_month=malloc(2*sizeof(char));
...
strncpy(day_month,data,2);
datas[j].month=atoi(day_month);

Other probable problem when :

        result[j].values[i]=value;

you always copy the same char * in a loop, if you suppose you will have different values this is false. There is a risk it has no ending null character because set through strncpy. May be also you will free it later (char * value=malloc(6*sizeof(char));). So, you probably have to strdup it but warning with the missing null char

bruno
  • 32,421
  • 7
  • 25
  • 37
  • Well that really depends on the length of the string in `data`. If it's only three respective one character then it's okay. But that's probably not the case. – Some programmer dude Feb 07 '19 at 17:20
  • @Someprogrammerdude yes not the case here year on 4 chars and risk for 2 chars for the day from the 10 – bruno Feb 07 '19 at 17:22
  • @bruno in that line result[j].values[i]=value; that you mention i did in fact wanted different values,what can i do to correct that problem?? – Joao Barata Feb 07 '19 at 17:36
  • @JoaoBarata as I said you need to _strdup_, but again warning with the perhaps missing null char – bruno Feb 07 '19 at 17:46
  • @bruno yeah that worked wonders,thank you ^^ Now I need to find that double free or corruption and core dumped – Joao Barata Feb 07 '19 at 17:53
  • @JoaoBarata Did you also correct my other remarks ? Can you use _valgrind_ ? This is a fantastic tool, you do not need to make a special compiling, just compile in debug mode to have the debug info, and rather than to do `progname arg1 ... argn` just do `valgrind progname arg1 ... argn` – bruno Feb 07 '19 at 17:54
  • @bruno I probably cant as im using a virtual machine of linux and i'm correcting your other remarks rn because as soon as i delete the line:strncpy(data,info,10); the errors seem to vanish xD – Joao Barata Feb 07 '19 at 18:00
  • @JoaoBarata if you are under a Linux even virtualized you can use _valgrind_ – bruno Feb 07 '19 at 18:01