I receive objects from Thread #1 - its a 3rd party lib code - my callback called on it.
Objects have fixed-length string fields wrapped:
typedef struct somestr_t {
char * Data;
int Len; } somestr_t;
I have to create copy of the objects by hand every time, before I can pass it further to my code. So amongst other things I copy these strings too using this helper:
inline void CopyStr(somestr_t * dest, somestr_t * src)
{
if (src->Len == 0) {
dest->Len = 0;
return;
}
char* data = new char[src->Len];
memcpy(data, src->Data, src->Len);
dest->Data = data;
dest->Len = src->Len;
}
Then somewhere down the road I delete the object and its string fields:
if (someobj != nullptr)
{
if (someobj ->somestr.Len != 0) delete someobj ->somestr.Data;
. . .
delete someobj ;
}
When I run valgrind I get these in places where I would expect the strings to be deleted:
==33332== Mismatched free() / delete / delete []
==33332== at 0x48478DD: operator delete(void*, unsigned long) (vg_replace_malloc.c:935)
==33332== by 0x41B517: cleanup() (Recorder.cpp:86)
==33332== by 0x41BB29: signal_callback(int) (Recorder.cpp:129)
==33332== by 0x4C11DAF: ??? (in /usr/lib64/libc.so.6)
==33332== by 0x4CD14D4: clock_nanosleep##GLIBC_2.17 (clock_nanosleep.c:48)
==33332== by 0x4CD6086: nanosleep (nanosleep.c:25)
==33332== by 0x4D02DE8: usleep (usleep.c:32)
==33332== by 0x41C3EF: Logger(void*) (LogThreads.h:28)
==33332== by 0x4C5C6C9: start_thread (pthread_create.c:443)
==33332== by 0x4BFC2B3: clone (clone.S:100)
==33332== Address 0xd661260 is 0 bytes inside a block of size 12 alloc'd
==33332== at 0x484622F: operator new[](unsigned long) (vg_replace_malloc.c:640)
==33332== by 0x419E72: CopyStr (CbOverrides.h:23)
and summary report:
==34077== HEAP SUMMARY:
==34077== in use at exit: 328,520 bytes in 3,828 blocks
==34077== total heap usage: 124,774 allocs, 120,946 frees, 559,945,294 bytes allocated
==34077==
==34077== LEAK SUMMARY:
==34077== definitely lost: 0 bytes in 0 blocks
==34077== indirectly lost: 0 bytes in 0 blocks
==34077== possibly lost: 0 bytes in 0 blocks
==34077== still reachable: 328,520 bytes in 3,828 blocks
==34077== suppressed: 0 bytes in 0 blocks
I never used valgrind (or any c++ tool) before so I am not sure - why mismatch delete is reported? why there are 328K unreleased memory on exit?
char* data = new char[src->Len];
and
if (someobj ->somestr.Len != 0) delete someobj ->somestr.Data;
That delete should be delete [].
Why are there still reachable: 425,333 bytes in 3,860 blocks. Sorry, my crystal ball isn't working.
Normally Valgrind does give a hint as to what you need to do
==19283== Rerun with --leak-check=full to see details of leaked memory
It's a little bit mean in that after you've done that it will tell you about another option
==21816== Reachable blocks (those to which a pointer was found) are not shown.
==21816== To see them, rerun with: --leak-check=full --show-leak-kinds=all
Try those and start working through the non-freed memory.
Related
I use doubly linked list to implement Deque in C++.
Destructor:
Deque::~Deque()
{
while (this->left_p)
{
node *temp = this->left_p;
this->left_p = this->left_p->next;
delete temp;
}
this->right_p = NULL;
}
when i use valgrind --leak-check=full ./a.out to check memory leak just to test my destructor` I got the following output:
==2636==
==2636== HEAP SUMMARY:
==2636== in use at exit: 72,704 bytes in 1 blocks
==2636== total heap usage: 1,003 allocs, 1,002 frees, 97,760 bytes allocated
==2636==
==2636== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==2636== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2636== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==2636== by 0x40106B9: call_init.part.0 (dl-init.c:72)
==2636== by 0x40107CA: call_init (dl-init.c:30)
==2636== by 0x40107CA: _dl_init (dl-init.c:120)
==2636== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==2636==
==2636== LEAK SUMMARY:
==2636== definitely lost: 0 bytes in 0 blocks
==2636== indirectly lost: 0 bytes in 0 blocks
==2636== possibly lost: 0 bytes in 0 blocks
==2636== still reachable: 72,704 bytes in 1 blocks
==2636== suppressed: 0 bytes in 0 blocks
==2636==
==2636== For counts of detected and suppressed errors, rerun with: -v
==2636== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I can't figure out why there is still ONE out of 1003 allocs not being free.
Why do i have one memory leak? what is wrong with my destructor?
Test code here:
/* Deque Test Program 6 */
#include <cstring>
#include <iostream>
#include "Deque.h"
using namespace std ;
int main (int argc, char * const argv[]) {
cout << "\n\nDeque Class Test Program 6 - START\n\n";
// Make a Deque
Deque * dq1 = new Deque();
for( int i = 0 ; i<1 ; i++ ){
dq1->push_left(1);
// dq1->display();
}
cout << "Size=" << dq1->size() << endl ;
// The destructor should delete all the nodes.
delete dq1 ;
cout << "\n\nDeque Class Test Program 6 - DONE\n\n";
return 0;
}
edit: remove implementation code.
Essentially, it's not your code's fault, it's valgrind's.
Check this other question that has had the same problem:
Valgrind: Memory still reachable with trivial program using <iostream>
Quoting from the post:
First of all: relax, it's probably not a bug, but a feature. Many implementations of the C++ standard libraries use their own memory pool allocators. Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.
Hope that helps :)
The memory leak reported by valgrind does not appear to be in your code:
==2636== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==2636== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2636== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==2636== by 0x40106B9: call_init.part.0 (dl-init.c:72)
==2636== by 0x40107CA: call_init (dl-init.c:30)
==2636== by 0x40107CA: _dl_init (dl-init.c:120)
This appears to be a heap allocation from within a constructor of a global object. (In theory, it could still come from your code if operator new is called as a tail call, so that it does not show up in the backtrace, but I don't see such an object declaration in your cdoe.)
It is also not an actual leak, it is just some data allocated on the heap at program start. If you install debugging information for libstdc++, then you might get a hint of what is actually being allocated. Then you could also set a breakpoint on call_init and step through the early process initialization, to see the constructors that are called.
This question already has answers here:
PRE-2016 Valgrind: Memory still reachable with trivial program using <iostream>
(3 answers)
Closed 6 years ago.
Here is simplified version of the code, I deleted everything that doesn't concern the problem.
#include <iostream>
#define N 3
int main() {
int *input;
int **cl;
input = new int[N];
cl = new int*[N];
for(int i = 0; i < N; i++) {
cl[i] = new int[N];
}
for(int i = 0; i < N; i++) {
delete[] cl[i];
}
delete[] cl;
delete[] input;
return 0;
}
And the valgrind output:
==5782== HEAP SUMMARY:
==5782== in use at exit: 72,704 bytes in 1 blocks
==5782== total heap usage: 6 allocs, 5 frees, 72,776 bytes allocated
==5782==
==5782== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==5782== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5782== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==5782== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==5782== by 0x40105FA: call_init (dl-init.c:30)
==5782== by 0x40105FA: _dl_init (dl-init.c:120)
==5782== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==5782==
==5782== LEAK SUMMARY:
==5782== definitely lost: 0 bytes in 0 blocks
==5782== indirectly lost: 0 bytes in 0 blocks
==5782== possibly lost: 0 bytes in 0 blocks
==5782== still reachable: 72,704 bytes in 1 blocks
==5782== suppressed: 0 bytes in 0 blocks
==5782==
==5782== For counts of detected and suppressed errors, rerun with: -v
==5782== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I just started to learn C++, maybe there is some stupid error that I cannot see.
I know I should also check for example if there was no "out of memory" error when allocating, but I ignore it so that code is more clear. I also know I could use e.g. vector and don't care for the allocation, but I'm still concerned what I do wrong.
C++ provides you with tools, that encapsulate memory management for you.
#include <iostream>
#include <vector>
int main() {
// read the size for the vectors
int n;
std::cin >> n >> '\n';
// allocate vector with n elements
auto input = std::vector<int>{n};
// read the elements
for(int i = 0; i < n; i++) {
std::cin >> std::setw(1) >> input[i];
}
// print them
for(const auto& d : input) {
std::cout << d << std::endl;
}
// allocate the vectors and store 1 in each field.
auto Cl = std::vector<std::vector<int>>{n, std::vector<int>{n, 1}};
auto Cr = std::vector<std::vector<int>>{n, std::vector<int>{n, 1}};
return 0;
// will safely release all the memory here.
}
This looks a lot more like C++, and less like C. The vectors will handle all the memory management automatically for you.
Beware: I have not tested this code, so it will probably contain some bugs. I assume C++11 syntax, but it should be easy to change the code to older C++ syntax as well.
Now that you've added the valgrind output it's clearly the same issue as the one that has an answer here: Valgrind: Memory still reachable with trivial program using <iostream>
The short story is that it's not your code that causes that report. You can remove everything from main() and just return and valgrind will still give you that leak.
Read the accepted answer on that question for the explanation.
This question relates to a previous question I asked a year ago.
I am using WordNet 3.0 which was written a long time ago in C (circa 1996 I think).
In order to try and stay away from memory management, I asked how I could wrap std::shared_ptr around the old struct Synset used by WordNet.
A reference table shows the WordNet-3.0 functions, and inspection of the actual header shows that the SynsetPtr,
which functions traceptrs_ds and findtheinfo_ds return, are pointers to ss or Synset.
In my previous question I chose to remove the pointer,
and then wrap it around a shared_ptr like so:
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(findtheinfo_ds(searchstr, pos, ptr_type, sense_num),
free_syns);
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(traceptrs_ds(synptr, ptr_type, pos, depth),
free_synset);
I have two loops, one which iterates senses by following the nextss, and one which traverses a tree list by calling traceptrs_ds.
Those are the two loops (oversimplified):
std::shared_ptr<Synset> synsets;
synsets = std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(findtheinfo_ds(const_cast<char*>(key.c_str()), lexical, HYPERPTR, ALLSENSES),free_syns);
if (synsets)
{
std::shared_ptr<Synset> sense_ptr = synsets;
while(sense_ptr)
{
graph g = graph();
iterate(sense_ptr, nullptr, g, 0, lexical);
sense_ptr = std::shared_ptr<std::remove_pointer<SynsetPtr>::type>(sense_ptr->nextss);
}
}
iterate(
std::shared_ptr<Synset> ptr,
std::shared_ptr<layer> last,
graph & rhs,
int i,
int lexical
)
{
while (ptr)
{
i++;
ptr = std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(traceptrs_ds(ptr.get(), HYPERPTR, lexical, 1), free_synset);
}
}
From what I understand (feel free to correct me) many std::shared_ptr are wrapping around the same memory,
and when their destructor is called, they try to free the same memory.
How can I prevent this from happening?
I know that findtheinfo_ds returns a linked list, and that each call to traceptrs_ds appears to iterate that list.
I image that the best approach would be to wrap only one std::shared_ptr which is going to call the Synset destructor free_synset, instead of doing it many times.
How can I stop this from happening?
Assuming there is no solution to prevent this from happening,
how can the destructors of the many std::shared_ptr that map to the same area, only free once?
I guess this is a bad/ugly way, but it may be easier?
The valgrind output:
==3066== Invalid read of size 8
==3066== at 0x52C3B4C: free_synset (in /usr/lib/libwordnet-3.0.so)
==3066== by 0x4E6E2D9: std::_Sp_counted_deleter<ss*, void (*)(ss*), std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:463)
==3066== by 0x403C5F: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:149)
==3066== by 0x403AD8: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:666)
==3066== by 0x4E61DB7: std::__shared_ptr<ss, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:914)
==3066== by 0x4E61DD1: std::shared_ptr<ss>::~shared_ptr() (shared_ptr.h:93)
==3066== by 0x4E6161A: smnet::hyper_handler::operator()(std::string, int) (hyper_handler.cpp:22)
==3066== by 0x4036D6: main (hypernym.cpp:16)
==3066== Address 0x10 is not stack'd, malloc'd or (recently) free'd
==3066== Process terminating with default action of signal 11 (SIGSEGV)
==3066== Access not within mapped region at address 0x10
==3066== at 0x52C3B4C: free_synset (in /usr/lib/libwordnet-3.0.so)
==3066== by 0x4E6E2D9: std::_Sp_counted_deleter<ss*, void (*)(ss*), std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:463)
==3066== by 0x403C5F: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:149)
==3066== by 0x403AD8: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:666)
==3066== by 0x4E61DB7: std::__shared_ptr<ss, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:914)
==3066== by 0x4E61DD1: std::shared_ptr<ss>::~shared_ptr() (shared_ptr.h:93)
==3066== by 0x4E6161A: smnet::hyper_handler::operator()(std::string, int) (hyper_handler.cpp:22)
==3066== by 0x4036D6: main (hypernym.cpp:16)
==3066== LEAK SUMMARY:
==3066== definitely lost: 0 bytes in 0 blocks
==3066== indirectly lost: 0 bytes in 0 blocks
==3066== possibly lost: 251 bytes in 8 blocks
==3066== still reachable: 19,964 bytes in 90 blocks
==3066== suppressed: 0 bytes in 0 blocks
==3066== Reachable blocks (those to which a pointer was found) are not shown.
==3066== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==3066==
==3066== For counts of detected and suppressed errors, rerun with: -v
==3066== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
fish: “valgrind --leak-check=full ./hy…” terminated by signal SIGSEGV (Address boundary error)
Well, after searching quite a bit, I found the solution using struct functors and lambdas. Granted its not pretty (in fact its quite ugly) but seems to work:
struct sense_del
{
void operator()(Synset *ptr)
{
if (ptr)
free_syns(ptr);
}
};
struct trace_del
{
void operator()(Synset *ptr)
{
if (ptr)
free_synset(ptr);
}
};
std::shared_ptr<Synset>
shared_findtheinfo_ds(std::string key, int gram_type, int ptr_type, int sense_num)
{
wn_init_once();
std::shared_ptr<Synset> sp(findtheinfo_ds(const_cast<char*>(key.c_str()), gram_type, ptr_type, sense_num),
[](Synset * ptr){sense_del()(ptr);});
return sp;
}
std::shared_ptr<Synset>
shared_traceptrs_ds(SynsetPtr synptr, int ptr_type, int gram_type, int depth)
{
assert(synptr);
std::shared_ptr<Synset> sp(traceptrs_ds(synptr, ptr_type, gram_type, depth),
[](Synset *ptr){trace_del()(ptr);});
return sp;
}
FYI, for anyone working on Wordnet, the correct way of iteration for Hypernyms is this:
if (auto ss_ptr = findtheinfo_ds(const_cast<char*>(key.c_str()), lexical, HYPERPTR, ALLSENSES))
{
while(ss_ptr)
{
if (SynsetPtr trc_ptr = traceptrs_ds(ss_ptr, HYPERPTR, lexical, 1))
{
do_smth_with_it(trc_ptr);
free_syns(trc_ptr);
}
// get next sense
ss_ptr = ss_ptr->nextss;
}
free_syns(ss_ptr);
}
I have a class unix_socket that has a double* as an attribute, and allocates memory with new in its constructor:
class unix_socket::unix_socket(){
//...
array_recvd=new double[10];
//...
}
and consequently I am using delete[] in its destructor in order to free the memory:
unix_socket::~unix_socket(){
//..
delete[] array_recvd;
//...
}
However, when using Valgrind to check for memory leaks in the program, the memory used by the array isn't freed:
==4683== HEAP SUMMARY:
==4683== in use at exit: 80 bytes in 1 blocks
==4683== total heap usage: 2 allocs, 1 frees, 648 bytes allocated
==4683==
==4683== Searching for pointers to 1 not-freed blocks
==4683== Checked 188,184 bytes
==4683==
==4683== 80 bytes in 1 blocks are still reachable in loss record 1 of 1
==4683== at 0x4C2BBA4: operator new[](unsigned long) (vg_replace_malloc.c:363)
==4683== by 0x406503: unix_socket::unix_socket() (in /home/joao/CloudPT/Bolsa/Webots/controllers/darwin-pi2/client)
==4683== by 0x402355: main (in /home/joao/CloudPT/Bolsa/Webots/controllers/darwin-pi2/client)
==4683==
==4683== LEAK SUMMARY:
==4683== definitely lost: 0 bytes in 0 blocks
==4683== indirectly lost: 0 bytes in 0 blocks
==4683== possibly lost: 0 bytes in 0 blocks
==4683== still reachable: 80 bytes in 1 blocks
==4683== suppressed: 0 bytes in 0 blocks
I'm sure this leak is due to the vector_recvd array_recvd, since it is only present when I have it as an attribute. What exactly am I doing wrong? How would I free the memory allocated by the array of doubles?
EDIT: So this is the main.cpp I'm using to replicate this issue:
int main () {
unix_socket client;
client.initSocket(DEFAULT_SOCKET_PATH,CLIENT_MODE);
for (int i = 0; i < 100; ++i){
client.sendVectorXd(VectorXd::Ones(30));
}
client.closeSocket();
return 0;
}
Probably relevant: this issue is only present when the socket connection is refused (no server waiting for the client).
EDIT 2: So I've found the problem, and it was indeed in initSocket(). If connecting to a socket server somehow failed (as was the case), I had exit(1):
if (connect(client_sock, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
I assumed that calling exit() would call the destructors, I see now that's not the case.
Thats the Store Credit problem on Google code jam.
https://code.google.com/codejam/contest/351101/dashboard#s=p0
My code gives out a SIGSEGV after running the large test. But the answer is correct!
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int ps[1000]={0};
vector<int> indice[1000];
int main() {
int cases; scanf("%d", &cases);
for(int j=1;j<=cases;j++) {
printf("Case #%d: ", j);
int c, is; scanf("%d%d", &c, &is);
for(int i=0;i<=c;i++) ps[i]=0;
for(int i=0;i<=c;i++) indice[i].clear();
for (int i = 0; i < is; i++) {
int it; scanf("%d", &it);
indice[it].push_back(i+1);
ps[it]=1;
if (c-it>0&&ps[c-it]) {
int a, b;
a = indice[it][0];
b = indice[c-it][0];
if(c==2*it&&indice[it].size()>1) {
b=indice[it][1];
}
if (a!=b) {
printf("%d %d\n", min(a,b),max(a,b));
}
}
}
}
return 0;
}
So I use valgrind to find out what's going on .. but it seems that it's not my problem.
==17599== Invalid free() / delete / delete[] / realloc()
==17599== at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17599== by 0x401669: __gnu_cxx::new_allocator<int>::deallocate(int*, unsigned long) (new_allocator.h:98)
==17599== by 0x4013CD: std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) (stl_vector.h:156)
==17599== by 0x400F60: std::_Vector_base<int, std::allocator<int> >::~_Vector_base() (stl_vector.h:142)
==17599== by 0x400D8D: std::vector<int, std::allocator<int> >::~vector() (stl_vector.h:351)
==17599== by 0x400C48: __tcf_0 (a.cpp:6)
==17599== by 0x5383900: __run_exit_handlers (exit.c:78)
==17599== by 0x5383984: exit (exit.c:100)
==17599== by 0x5369773: (below main) (libc-start.c:258)
==17599== Address 0x1 is not stack'd, malloc'd or (recently) free'd
==17599==
==17599==
==17599== HEAP SUMMARY:
==17599== in use at exit: 128 bytes in 1 blocks
==17599== total heap usage: 4,527 allocs, 4,527 frees, 113,664 bytes allocated
==17599==
==17599== LEAK SUMMARY:
==17599== definitely lost: 0 bytes in 0 blocks
==17599== indirectly lost: 0 bytes in 0 blocks
==17599== possibly lost: 0 bytes in 0 blocks
==17599== still reachable: 128 bytes in 1 blocks
==17599== suppressed: 0 bytes in 0 blocks
==17599== Rerun with --leak-check=full to see details of leaked memory
==17599==
==17599== For counts of detected and suppressed errors, rerun with: -v
==17599== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
I'm so confused... Could anybody tell me what's going on? I'm a newbie of C++ ..
Thank you very much.
As I understand valgrind, it can't detect that you are writing outside of the bounds of arrays that are staticly allocated. So let's allocate them on the heap.
vector<int> *indice = new vector<int>[1000];
int *ps = new int[1000];
Then, you will see errors come out of valgrind. Including:
==7168== Invalid read of size 8
==7168== at 0x4008D6: main (stl_vector.h:735)
==7168== Address 0x4c39e10 is 8 bytes after a block of size 24,008 alloc'd
==7168== at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==7168== by 0x400791: global constructors keyed to indice (foo.cc:6)
==7168== by 0x400C35: ??? (in /tmp/foo)
==7168== by 0x4005F2: ??? (in /tmp/foo)
==7168==
==7168== Invalid read of size 8
==7168== at 0x4008DA: main (stl_vector.h:735)
==7168== Address 0x4c39e18 is 16 bytes after a block of size 24,008 alloc'd
==7168== at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==7168== by 0x400791: global constructors keyed to indice (foo.cc:6)
==7168== by 0x400C35: ??? (in /tmp/foo)
==7168== by 0x4005F2: ??? (in /tmp/foo)
==7168==
And using gdb, I can see that the SIGSEGV occurs when you access indice[1433], which is outside of the bounds of indice.
I also imagine that your actual issue is that for the large dataset, the variables bounds are listed as:
N = 50
3 ≤ I ≤ 2000
Are you sure you shouldn't be allocating 2001 elements, instead of 1000?