#memory leak no idea where

38 messages ยท Page 1 of 1 (latest)

dreamy raft
wise egretBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

minor copper
#

did you try using asan?

dreamy raft
#

nope whats that

wise egretBOT
#
Address Sanitizer

Memory errors in C and C++ are easy to make and they can be very hard to debug because they can manifest far from their source. Address sanitizer is a runtime checker that identifies memory errors at their source and makes debugging much simpler. Address sanitizer is available for gcc/clang on linux and msvc on windows. To use it simply pass -fsanitize=address to the compiler.

Note: Make sure to turn on debug symbols with -g for gcc/clang and -Zi for msvc.

ce Example

How to read sanitizer output

The first few lines tell you the problem, heap-use-after-free, due to performing a READ of size 4, at example.c line 7 (from the first line of the stack trace).

==1==ERROR: AddressSanitizer: heap-use-after-free on address ....
READ of size 4 at 0x602000000010 thread T0
    #0 0x40120f in main /app/example.c:7
    #1 0x7fda58629d8f  (...)
    #2 0x7fda58629e3f in __libc_start_main (...)
    #3 0x4010b4 in _start (...)

Additional information is also included such as where the allocation was performed and where the allocation was freed.

See Also
  • Other sanitizers exist and can be similarly helpful, including ubsan, threadsan, and memorysan.
dreamy raft
#

oh yeah i tried

minor copper
#

and?

dreamy raft
#

i cant replicate the error

#

but the program where i put the code finds an issue

#

if i knew where it happened it would be so much easier

minor copper
#

again - asan is the tool you should use to help you find said leak. please use it

#

if you don't like asan for whatever reason you can use valgrind instead

#

(in this particular case)

dreamy raft
#

yes i know, but no matter what i try to input i cant replicate the thing

minor copper
#

how do you know there is a leak in the first place then?

dreamy raft
#

the testing environment says there is

#

it has special edge cases it tests

#

but i cant replicate them

minor copper
#

i assume you don't have access to these edge cases then?

dreamy raft
#

yes

pale raven
dreamy raft
#

uh sure i guess

#
#include <stdlib.h>

#define MAX_SIZE 100000

typedef struct {
    long long from;  
    long long to;     
    long long daily_distribution;   
    long long daily_wage;      
} Lorry;

typedef struct {
    long long distribution;
    long long price;
} Day;

Lorry makeLorry (long long from, long long to, long long daily_distribution, long long daily_wage) {
  Lorry res = {from, to, daily_distribution, daily_wage};
  return res;
}

int nespravnyVstup() {
    printf("Nespravny vstup.\n");
    return 1;
}

long long binarySearchDayByGoods(Day *arr, long long length, long long goods, long long initial_day) {
    long long left = initial_day, right = length - 1;
    long long result = -1;
    while (left <= right) {
        long long mid = left + (right - left) / 2;
        if ((arr + mid)->distribution >= goods) {
            result = mid; 
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return result;
}


int main(void) {
    char spec = ' ', br_last = ' ';
    unsigned length = 0;
    Lorry lorry_list[MAX_SIZE];
    long long last_day = 0;

    printf("Moznosti dopravy:\n");
    if (scanf(" %c", &spec) != 1 || spec != '{') return nespravnyVstup();
    for(int i = 0; i < MAX_SIZE; i++) { // [ no - no , no , no ]
        long long a, b, c, d = 0;
        if (scanf(" [ %lld - %lld , %lld , %lld %c", &a, &b, &c, &d, &br_last) != 5 ||
                a > b || a < 0 || b < 0 || 
                c <= 0 || d <= 0 || br_last != ']') return nespravnyVstup();
        
        lorry_list[i] = makeLorry(a, b, c, d);
        if (b > last_day) last_day = b;
        length++;
        scanf(" %c", &spec);
        if (spec == '}') break;
        else if (spec == ',') continue;
        else return nespravnyVstup();
    }```
#
    for (unsigned i = 0; i < length; i++) {
        (list_of_days + lorry_list[i].from)->distribution += lorry_list[i].daily_distribution;
        (list_of_days + lorry_list[i].from)->price += lorry_list[i].daily_wage;
        if (lorry_list[i].to + 1 <= last_day) {
            (list_of_days + (lorry_list[i].to + 1))->distribution += -lorry_list[i].daily_distribution; 
            (list_of_days + (lorry_list[i].to + 1))->price += -lorry_list[i].daily_wage;
        }
    }

    long long total_price = 0, total_goods = 0, balance_price = 0, balance_goods = 0;
    for (unsigned i = 0; i < last_day + 1; i++) {
        //printf("ch %lld %lld\n", (list_of_days + i)->price, (list_of_days + i)->distribution);
        balance_price += (list_of_days + i)->price;
        balance_goods += (list_of_days + i)->distribution;
        //printf("__%lld__%lld\n", balance_goods, balance_price);
        total_price += balance_price;
        total_goods += balance_goods;
        (list_of_days + i)->price = total_price;
        (list_of_days + i)->distribution = total_goods;
        //printf("%d %lld %lld\n", i, total_price, total_goods);
    }

    long long max_cargo = (list_of_days + last_day)->distribution;


    printf("Naklad:\n");
    while(1) {
        long long day = 0;
        long long goods = 0;
        int out = scanf(" %lld %lld", &day, &goods);
        if (out != 2 || day < 0 || goods <= 0) {
            if (out == EOF) {
                free(list_of_days);
                list_of_days = NULL;
                return 0;
            }
            printf("Nespravny vstup.\n");
            free(list_of_days);
            list_of_days = NULL;
            return 0;
        }```
#
        if (day == 0) {
            zero_day_goods = 0;
            zero_day_price = 0;
        } else {
            zero_day_goods = (list_of_days + (day - 1))->distribution;
            zero_day_price = (list_of_days + (day - 1))->price;
        }
        zero_day_goods += goods;
        if (zero_day_goods > max_cargo) {
            printf("Prilis velky naklad, nelze odvezt.\n");
            continue;
        }
        long long new_day = binarySearchDayByGoods(list_of_days, last_day + 1, zero_day_goods, day);
        if (new_day == -1) {
            printf("Prilis velky naklad, nelze odvezt.\n");
            continue;
        }
        long long new_price = (list_of_days + new_day)->price - zero_day_price;
        printf("Konec: %lld, cena: %lld\n", new_day, new_price);
    }
}```
minor copper
#
if (out != 2 || day < 0 || goods <= 0) {
  if (out == EOF) {
    free(list_of_days);
    list_of_days = NULL;
    return 0;
  }
  printf("Nespravny vstup.\n");
  free(list_of_days);
  list_of_days = NULL;
  return 0;
}```
is a bit strange don't you think. ![this](https://cdn.discordapp.com/emojis/1185236833911713873.webp?size=128 "this") is equivalent to:
```c
if (out != 2 || day < 0 || goods <= 0) {
  if (out != EOF) {
    printf("Nespravny vstup.\n");
  }
  
  free(list_of_days);
  list_of_days = NULL;
  return 0;
}```
no?

in any case - i personally fail to see a scenario in which case the loop exits (normally) while failing to `free` `list_of_days`
dreamy raft
#

same

#

its a bitly strangely set ye

#

but there is something

#

no idea what

#

might be something with the array

minor copper
#

well... unless the program crashes before it reached the loop ๐Ÿ™‚
is there a possibility you access any of your arrays out of bounds in the section above the loop?

dreamy raft
#

i tried

#

but that didnt lead me anywhere

pale raven
#

What's the objective of your program?

gaunt hound
#

Could it be that the testing environment is doing something as simple as counting the number of calloc and free calls? Your code has two free calls and one calloc call though the execution path will never execute both of them. Just a thought.

still dove
#

write lots of assertions. a lot!

dreamy raft
#

!solved