Check if array index is out of range in Dr Memory - c

I need to check if an array index is out of range by using Dr.Memory. I don't use dynamic memory allocation in this case.
When I check this code with Dr.Memory. I'm using Windows 11.
int main() {
clock_t start, end;
float cpu_time_used;
start = clock();
int array[5] = {2, 4, 5, 6, 7};
int number = array[10];
printf("This is a number: %i\n", number);
end = clock();
cpu_time_used = ((float) (end - start)) / CLOCKS_PER_SEC;
printf("\nTotal speed was %f\n", cpu_time_used);
return EXIT_SUCCESS;
}
I get this output from Dr.Memory. As you can see, no complaining about that the index is out of range. Why?
Dr. Memory version 2.5.0 build 0 built on Oct 18 2021 03:01:22
Windows version: WinVer=105;Rel=2009;Build=22000;Edition=Professional
Dr. Memory results for pid 9640: "CControl.exe"
Application cmdline: ""C:\Users\dmn\OneDrive - ITH\Dokument\Projekt\Eclipse\CControl\Debug\CControl.exe""
Recorded 124 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin64\suppress-default.txt
Error #1: UNADDRESSABLE ACCESS beyond top of stack: reading 0x000000164a9ff980-0x000000164a9ff988 8 byte(s)
# 0 ___chkstk_ms [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:132]
# 1 _pei386_runtime_relocator
# 2 __tmainCRTStartup
# 3 .l_start
# 4 ntdll.dll!RtlUserThreadStart
Note: #0:00:00.097 in thread 18604
Note: 0x000000164a9ff980 refers to 664 byte(s) beyond the top of the stack 0x000000164a9ffc18
Note: instruction: or $0x0000000000000000 (%rcx) -> (%rcx)
Error #2: UNADDRESSABLE ACCESS beyond top of stack: reading 0x000000164a9ffa50-0x000000164a9ffa58 8 byte(s)
# 0 ___chkstk_ms [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:132]
# 1 __pformat_int.isra.0 [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 2 __mingw_pformat [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 3 __mingw_vfprintf [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 4 printf
# 5 main
Note: #0:00:00.135 in thread 18604
Note: 0x000000164a9ffa50 refers to 8 byte(s) beyond the top of the stack 0x000000164a9ffa58
Note: instruction: or $0x0000000000000000 (%rcx) -> (%rcx)
Error #3: UNINITIALIZED READ: reading register rcx
# 0 __pformat_int.isra.0 [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 1 __mingw_pformat [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 2 __mingw_vfprintf [../../../../../src/gcc-11.2.0/libgcc/config/i386/cygwin.S:138]
# 3 printf
# 4 main
Note: #0:00:00.135 in thread 18604
Note: instruction: test %rcx %rcx
Error #4: POSSIBLE LEAK 98 direct bytes 0x00000153bd9001c0-0x00000153bd900222 + 0 indirect bytes
# 0 replace_malloc [d:\a\drmemory\drmemory\common\alloc_replace.c:2580]
# 1 msvcrt.dll!malloc_crt
# 2 msvcrt.dll!_setargv
# 3 msvcrt.dll!_getmainargs
# 4 pre_cpp_init
# 5 msvcrt.dll!initterm
# 6 __tmainCRTStartup
# 7 .l_start
# 8 ntdll.dll!RtlUserThreadStart
===========================================================================
FINAL SUMMARY:
DUPLICATE ERROR COUNTS:
Error # 1: 2
Error # 2: 2
SUPPRESSIONS USED:
ERRORS FOUND:
2 unique, 4 total unaddressable access(es)
1 unique, 1 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
0 unique, 0 total, 0 byte(s) of leak(s)
1 unique, 1 total, 98 byte(s) of possible leak(s)
ERRORS IGNORED:
3 unique, 3 total, 113 byte(s) of still-reachable allocation(s)
(re-run with "-show_reachable" for details)
Details: C:\Users\dmn\AppData\Roaming\Dr. Memory\DrMemory-CControl.exe.9640.000\results.txt

Related

Why is there memory leaks with SDL2 (2.0.14) dll?

I am using SDL2 version 2.0.14. This is the current stable version.
I noticed that any program I write with SDL2 has memory leaks. For example
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("title",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, SDL_WINDOW_OPENGL);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
This is the main.c file. I build it with gcc main.c -o main.exe -lSDL2 -lSDL2main
If I run drmemory main.exe this is what I get -
ERRORS FOUND:
1 unique, 2 total unaddressable access(es)
6 unique, 6 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
1 unique, 1 total, 88 byte(s) of leak(s)
1 unique, 1 total, 26 byte(s) of possible leak(s)
I don't see why this program has leaks at all. I tried to find out what is wrong and came across this question
Although this is already answered, I don't see how this solves my issue. I want to know why am I having these leaks and how to fix them. Also do I need to worry about those unaddressable and uninitialized accesses diagnosed by Dr. Memory.
I suspect it has to do something with the SDL2.dll I downloaded from SDL2. I am using the win32-x64 dll.
EDIT
Here is the full 'error' details
Dr. Memory version 2.3.0 build 1 built on Feb 6 2020 06:07:09
Windows version: WinVer=63;Rel=;Build=9600;Edition=Professional
Dr. Memory results for pid 4868: "main.exe"
Application cmdline: "main.exe"
Recorded 118 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin64\suppress-default.txt
Error #1: UNADDRESSABLE ACCESS beyond top of stack: reading 0x000000000023fb70-0x000000000023fb78 8 byte(s)
# 0 .text [../../../../../src/gcc-8.1.0/libgcc/config/i386/cygwin.S:132]
# 1 _pei386_runtime_relocator
# 2 __tmainCRTStartup
# 3 .l_start
# 4 KERNEL32.dll!BaseThreadInitThunk +0x21 (0x00007ff902e81412 <KERNEL32.dll+0x1412>)
Note: #0:00:00.281 in thread 3800
Note: 0x000000000023fb70 refers to 600 byte(s) beyond the top of the stack 0x000000000023fdc8
Note: instruction: or $0x0000000000000000 (%rcx) -> (%rcx)
Error #2: UNINITIALIZED READ: reading 0x000000000023eeec-0x000000000023eef0 4 byte(s) within 0x000000000023eee8-0x000000000023eef0
# 0 system call NtGdiOpenDCW parameter value #5
# 1 GDI32.dll!GetNearestColor +0x21f (0x00007ff903152650 <GDI32.dll+0x12650>)
# 2 GDI32.dll!GetNearestColor +0x30c (0x00007ff90315273d <GDI32.dll+0x1273d>)
# 3 GDI32.dll!CreateDCW +0x12 (0x00007ff903152783 <GDI32.dll+0x12783>)
# 4 SDL2.dll!? +0x0 (0x0000000073eae403 <SDL2.dll+0x10e403>)
# 5 SDL2.dll!? +0x0 (0x0000000073eae781 <SDL2.dll+0x10e781>)
# 6 USER32.dll!mouse_event +0x1f9 (0x00007ff90532df1a <USER32.dll+0xdf1a>)
# 7 SDL2.dll!? +0x0 (0x0000000073eae91a <SDL2.dll+0x10e91a>)
# 8 SDL2.dll!? +0x0 (0x0000000073eb1d9d <SDL2.dll+0x111d9d>)
# 9 SDL2.dll!? +0x0 (0x0000000073e760ce <SDL2.dll+0xd60ce>)
#10 SDL2.dll!? +0x0 (0x0000000073da1547 <SDL2.dll+0x1547>)
#11 main
Note: #0:00:02.451 in thread 3800
Error #3: UNINITIALIZED READ: reading 0x000000000023f734-0x000000000023f738 4 byte(s) within 0x000000000023f730-0x000000000023f738
# 0 system call NtUserCreateWindowEx parameter value #14
# 1 USER32.dll!IsCharAlphaW +0x20e (0x00007ff905329d4f <USER32.dll+0x9d4f>)
# 2 USER32.dll!IsCharAlphaW +0x436 (0x00007ff905329f77 <USER32.dll+0x9f77>)
# 3 USER32.dll!CreateWindowExW +0x7d (0x00007ff90532a03e <USER32.dll+0xa03e>)
# 4 SDL2.dll!? +0x0 (0x0000000073eaffe9 <SDL2.dll+0x10ffe9>)
# 5 SDL2.dll!? +0x0 (0x0000000073eb08fc <SDL2.dll+0x1108fc>)
# 6 SDL2.dll!? +0x0 (0x0000000073e740b7 <SDL2.dll+0xd40b7>)
# 7 SDL2.dll!? +0x0 (0x0000000073e755df <SDL2.dll+0xd55df>)
# 8 main
Note: #0:00:02.839 in thread 3800
Error #4: UNINITIALIZED READ: reading 0x000000000023f7d4-0x000000000023f7d8 4 byte(s) within 0x000000000023f7d0-0x000000000023f7d8
# 0 system call NtUserCreateWindowEx parameter value #14
# 1 USER32.dll!IsCharAlphaW +0x20e (0x00007ff905329d4f <USER32.dll+0x9d4f>)
# 2 USER32.dll!IsCharAlphaW +0x436 (0x00007ff905329f77 <USER32.dll+0x9f77>)
# 3 USER32.dll!CreateWindowExW +0x7d (0x00007ff90532a03e <USER32.dll+0xa03e>)
# 4 SDL2.dll!? +0x0 (0x0000000073eb2b9c <SDL2.dll+0x112b9c>)
# 5 SDL2.dll!? +0x0 (0x0000000073e7584d <SDL2.dll+0xd584d>)
# 6 main
Note: #0:00:03.636 in thread 3800
Error #5: UNINITIALIZED READ: reading 0x000000000023f494-0x000000000023f498 4 byte(s) within 0x000000000023f490-0x000000000023f498
# 0 system call NtUserCreateWindowEx parameter value #14
# 1 USER32.dll!IsCharAlphaW +0x20e (0x00007ff905329d4f <USER32.dll+0x9d4f>)
# 2 USER32.dll!IsCharAlphaW +0x436 (0x00007ff905329f77 <USER32.dll+0x9f77>)
# 3 USER32.dll!CreateWindowExW +0x7d (0x00007ff90532a03e <USER32.dll+0xa03e>)
# 4 SDL2.dll!? +0x0 (0x0000000073eaf7fa <SDL2.dll+0x10f7fa>)
# 5 SDL2.dll!? +0x0 (0x0000000073eafaed <SDL2.dll+0x10faed>)
# 6 SDL2.dll!? +0x0 (0x0000000073eb099d <SDL2.dll+0x11099d>)
# 7 SDL2.dll!? +0x0 (0x0000000073eb2c5b <SDL2.dll+0x112c5b>)
# 8 SDL2.dll!? +0x0 (0x0000000073e7584d <SDL2.dll+0xd584d>)
# 9 main
Note: #0:00:03.890 in thread 3800
Error #6: UNINITIALIZED READ: reading 0x000000000023f494-0x000000000023f498 4 byte(s) within 0x000000000023f490-0x000000000023f498
# 0 system call NtUserCreateWindowEx parameter value #14
# 1 USER32.dll!IsCharAlphaW +0x20e (0x00007ff905329d4f <USER32.dll+0x9d4f>)
# 2 USER32.dll!IsCharAlphaW +0x436 (0x00007ff905329f77 <USER32.dll+0x9f77>)
# 3 USER32.dll!CreateWindowExW +0x7d (0x00007ff90532a03e <USER32.dll+0xa03e>)
# 4 SDL2.dll!? +0x0 (0x0000000073eaf7fa <SDL2.dll+0x10f7fa>)
# 5 SDL2.dll!? +0x0 (0x0000000073eafe55 <SDL2.dll+0x10fe55>)
# 6 SDL2.dll!? +0x0 (0x0000000073eb099d <SDL2.dll+0x11099d>)
# 7 SDL2.dll!? +0x0 (0x0000000073eb2c5b <SDL2.dll+0x112c5b>)
# 8 SDL2.dll!? +0x0 (0x0000000073e7584d <SDL2.dll+0xd584d>)
# 9 main
Note: #0:00:03.947 in thread 3800
Error #7: UNINITIALIZED READ: reading 0x000000000023f6b0-0x000000000023f6b8 8 byte(s) within 0x000000000023f6a8-0x000000000023f6b8
# 0 system call NtUserTrackMouseEvent TRACKMOUSEEVENT post-dwFlags
# 1 SDL2.dll!? +0x0 (0x0000000073eb3bf2 <SDL2.dll+0x113bf2>)
# 2 SDL2.dll!? +0x0 (0x0000000073dcc1b7 <SDL2.dll+0x2c1b7>)
# 3 SDL2.dll!? +0x0 (0x0000000073dca237 <SDL2.dll+0x2a237>)
# 4 SDL2.dll!? +0x0 (0x0000000073dca7a8 <SDL2.dll+0x2a7a8>)
# 5 SDL2.dll!? +0x0 (0x0000000073ea90d8 <SDL2.dll+0x1090d8>)
# 6 USER32.dll!DispatchMessageW +0x15c (0x00007ff9053224fd <USER32.dll+0x24fd>)
# 7 USER32.dll!DispatchMessageW +0xc2 (0x00007ff905322463 <USER32.dll+0x2463>)
# 8 USER32.dll!CallWindowProcW +0x9a (0x00007ff905323ccb <USER32.dll+0x3ccb>)
# 9 OPENGL32.dll!glDebugEntry +0x1146b (0x00007ff8fa3928fc <OPENGL32.dll+0x428fc>)
#10 USER32.dll!DispatchMessageW +0x15c (0x00007ff9053224fd <USER32.dll+0x24fd>)
#11 USER32.dll!DispatchMessageW +0xc2 (0x00007ff905322463 <USER32.dll+0x2463>)
#12 USER32.dll!MsgWaitForMultipleObjects +0x141 (0x00007ff905323902 <USER32.dll+0x3902>)
#13 USER32.dll!MsgWaitForMultipleObjects +0x20d (0x00007ff9053239ce <USER32.dll+0x39ce>)
#14 USER32.dll!GetWindowLongW +0x10f (0x00007ff905326980 <USER32.dll+0x6980>)
#15 SDL2.dll!? +0x0 (0x0000000073e73b3c <SDL2.dll+0xd3b3c>)
#16 SDL2.dll!? +0x0 (0x0000000073e75896 <SDL2.dll+0xd5896>)
#17 main
Note: #0:00:06.599 in thread 3800
Error #8: LEAK 88 direct bytes 0x0000000002679b00-0x0000000002679b58 + 0 indirect bytes
# 0 replace_RtlAllocateHeap [d:\drmemory_package\common\alloc_replace.c:3771]
# 1 IMM32.dll!CtfImmGetTMAEFlags +0x1b4 (0x00007ff905013b35 <IMM32.dll+0x3b35>)
# 2 IMM32.dll!ImmGetContext +0x105 (0x00007ff905012396 <IMM32.dll+0x2396>)
# 3 SDL2.dll!? +0x0 (0x0000000073eaae90 <SDL2.dll+0x10ae90>)
# 4 SDL2.dll!? +0x0 (0x0000000073eab89b <SDL2.dll+0x10b89b>)
# 5 SDL2.dll!? +0x0 (0x0000000073dc8961 <SDL2.dll+0x28961>)
# 6 SDL2.dll!? +0x0 (0x0000000073ea90a4 <SDL2.dll+0x1090a4>)
# 7 USER32.dll!DispatchMessageW +0x15c (0x00007ff9053224fd <USER32.dll+0x24fd>)
# 8 USER32.dll!DispatchMessageW +0xc2 (0x00007ff905322463 <USER32.dll+0x2463>)
# 9 USER32.dll!CallWindowProcW +0x9a (0x00007ff905323ccb <USER32.dll+0x3ccb>)
#10 OPENGL32.dll!glDebugEntry +0x1146b (0x00007ff8fa3928fc <OPENGL32.dll+0x428fc>)
#11 USER32.dll!DispatchMessageW +0x15c (0x00007ff9053224fd <USER32.dll+0x24fd>)
Error #9: POSSIBLE LEAK 26 direct bytes 0x00000000029c01c0-0x00000000029c01da + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 msvcrt.dll!malloc_crt
# 2 msvcrt.dll!_setargv
# 3 msvcrt.dll!_getmainargs
# 4 pre_cpp_init
# 5 msvcrt.dll!initterm
# 6 __tmainCRTStartup
# 7 .l_start
# 8 KERNEL32.dll!BaseThreadInitThunk +0x21 (0x00007ff902e81412 <KERNEL32.dll+0x1412>)
===========================================================================
FINAL SUMMARY:
DUPLICATE ERROR COUNTS:
Error # 1: 2
SUPPRESSIONS USED:
ERRORS FOUND:
1 unique, 2 total unaddressable access(es)
6 unique, 6 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
1 unique, 1 total, 88 byte(s) of leak(s)
1 unique, 1 total, 26 byte(s) of possible leak(s)
ERRORS IGNORED:
91 potential error(s) (suspected false positives)
(details: C:\Users\Kabir\AppData\Roaming\Dr. Memory\DrMemory-main.exe.4868.000\potential_errors.txt)
10 potential leak(s) (suspected false positives)
(details: C:\Users\Kabir\AppData\Roaming\Dr. Memory\DrMemory-main.exe.4868.000\potential_errors.txt)
112 unique, 248 total, 34288 byte(s) of still-reachable allocation(s)
(re-run with "-show_reachable" for details)
Details: C:\Users\Kabir\AppData\Roaming\Dr. Memory\DrMemory-main.exe.4868.000\results.txt

Heap exhaustion while compiling lapack system with SBCL

While compiling the lapack system from the f2cl library, SBCL drops into the low-level debugger with this error message about heap exhaustion:
Heap exhausted during garbage collection: 0 bytes available, 64 requested.
Gen Boxed Unboxed LgBox LgUnbox Pin Alloc Waste Trig WP GCs Mem-age
0 0 0 0 0 0 0 0 26843545 0 0 0.0000
1 26205 12796 0 0 9 1277771072 213696 767547401 39001 1 1.3696
2 14599 27405 117 18 88 1114241264 266569488 2000000 42139 0 0.8257
3 0 0 0 0 0 0 0 2000000 0 0 0.0000
4 0 0 0 0 0 0 0 2000000 0 0 0.0000
5 0 0 0 0 0 0 0 2000000 0 0 0.0000
6 449 220 64 47 0 24788848 770192 2000000 780 0 0.0000
7 0 0 0 0 0 0 0 2000000 0 0 0.0000
Total bytes allocated = 2416801184
Dynamic-space-size bytes = 2684354560
GC control variables:
*GC-INHIBIT* = true
*GC-PENDING* = true
*STOP-FOR-GC-PENDING* = false
fatal error encountered in SBCL pid 31717(tid 0x7fbb53033280):
Heap exhausted, game over.
I found postings on the maxima mailing list that recommend increasing the heap size with the --dyanamic-space-size option for sbcl, so I tried that. Even when I gave it as much memory as my RAM (~7.44 GB) it still exhausted the heap, albeit after a much longer time. I'm not quite sure where to go from here. Any ideas?
System Specs: Arch Linux and SBCL 1.4.16.
High memory consumption during compilation may happen because you are asking a high amount of debugging information. I tried compiling lapack, which failed too. It happens that in my ~/.sbclrc, I have:
(sb-ext:restrict-compiler-policy 'debug 3)
(sb-ext:restrict-compiler-policy 'safety 3)
In a fresh SBCL, the compiler policy is as follows:
* (describe-compiler-policy)
Basic qualities:
COMPILATION-SPEED = 1
DEBUG = 3
SAFETY = 3
SPACE = 1
SPEED = 1
INHIBIT-WARNINGS = 1
Dependent qualities:
SB-C::CHECK-CONSTANT-MODIFICATION = 1 -> 3 (yes)
SB-C::TYPE-CHECK = 1 -> 3 (full)
SB-C::CHECK-TAG-EXISTENCE = 1 -> 3 (yes)
SB-C::LET-CONVERSION = 1 -> 0 (off)
SB-C:ALIEN-FUNCALL-SAVES-FP-AND-PC = 1 -> 3 (yes)
SB-C:VERIFY-ARG-COUNT = 1 -> 3 (yes)
SB-C::INSERT-DEBUG-CATCH = 1 -> 3 (yes)
SB-C::RECOGNIZE-SELF-CALLS = 1 -> 0 (no)
SB-C::FLOAT-ACCURACY = 1 -> 3 (full)
SB-C:INSERT-STEP-CONDITIONS = 1 -> 3 (full)
SB-C::COMPUTE-DEBUG-FUN = 1 -> 3 (yes)
SB-C::EVAL-STORE-SOURCE-FORM = 1 -> 3 (yes)
SB-C::PRESERVE-SINGLE-USE-DEBUG-VARIABLES = 1 -> 3 (yes)
SB-C::INSERT-ARRAY-BOUNDS-CHECKS = 1 -> 3 (yes)
SB-C::STORE-XREF-DATA = 1 -> 3 (yes)
SB-C:STORE-COVERAGE-DATA = 1 -> 0 (no)
SB-C::INSTRUMENT-CONSING = 1 -> 1 (no)
SB-C::STORE-CLOSURE-DEBUG-POINTER = 1 -> 0 (no)
SB-KERNEL:ALLOW-NON-RETURNING-TAIL-CALL = 1 -> 0 (no)
In particular, the policy is restricted as follows:
* (restrict-compiler-policy)
((SAFETY . 3) (DEBUG . 3))
Those are the minimal amount of debugging and safety required, which is thus at least 3 for both.
When I remove the debug restriction, with the following line:
* (restrict-compiler-policy 'debug)
((SAFETY . 3))
... then compiling the lapack system works, without changing the dynamic space size. Adding debugging information is fine when developing, and I'd encourage anyone to keep them at all time because you never know when you'll need to debug something, but in that case it is simply better to turn them off.
Just a quick note to add: that's a very old version of SBCL. If you can, you may want to consider upgrading to the latest.

Combining data of two vectors in a time series in R

I am a research assistent and have collected eye movement data, which I now try to analyze using R.
From the eye-tracker I use, every sample is marked as belonging to a saccade (which means the eye moves) or not and belonging to a blink or not. When someone starts to blink, the eye-tracker first identifies a saccade later identifies a blink. To be able to substitute all eye movement samples (lines in my data file), which belong to a blink, I need to create a variable that marks all saccades that contain a blink. A simple example is the following:
I have the data:
Data <- data.frame(Blink=c(0,0,0,1,1,0,0,0,1,1,0,0,0,0,0), Saccade=c(0,1,1,1,1,1,0,1,1,1,1,0,1,1,0))
I would like a variable like this as a result:
Data$Saccade_containing_blink <- c(0,1,1,1,1,1,0,1,1,1,1,0,0,0,0)
Which function would give me that result using R?
# example data
Data <- data.frame(Blink=c(0,0,0,1,1,0,0,0,1,1,0,0,0,0,0),
Saccade=c(0,1,1,1,1,1,0,1,1,1,1,0,1,1,0))
library(dplyr)
Data %>%
group_by(group = cumsum(Saccade==0)) %>% # group your Saccades
mutate(Saccade_containing_blink = max(Blink), # if there's a Blink update all rows within that Saccade
Saccade_containing_blink = ifelse(Saccade == 0, 0, Saccade_containing_blink)) %>% # update Saccade to exclude the 0s (0s separate Saccades)
ungroup() %>% # ungroup data
select(-group) # remove grouping column
# # A tibble: 15 x 3
# Blink Saccade Saccade_containing_blink
# <dbl> <dbl> <dbl>
# 1 0 0 0
# 2 0 1 1
# 3 0 1 1
# 4 1 1 1
# 5 1 1 1
# 6 0 1 1
# 7 0 0 0
# 8 0 1 1
# 9 1 1 1
# 10 1 1 1
# 11 0 1 1
# 12 0 0 0
# 13 0 1 0
# 14 0 1 0
# 15 0 0 0
The philosophy of this approach is to be able to group the Saccade column and check if there's a Blink in at least one of the rows within each Saccade. I assume that Saccades are separated by a 0 in column Saccade.

Dynamic Array of matrix

I'm in difficult to resolve this problem:
typedef struct {
.....
} info;
info array[1000][10][10]; //now i have this 3d matrix
For memory optimization i want to allocate dynamically the first dimension: i want to have a dynamic array of matrix[10][10]. So i have declare a pointer like this:
info *array[10][10];
But how to do a malloc do add for example N matrix[10][10] to the array?
I tried:
info *array[10][10]=malloc(N*sizeof(array));
As described by WhozCraig in the coments and kiranBiradar in his answer, your attempt to allocate:
info *array[10][10]=malloc(N*sizeof(array));
was an attempt to allocate for an array or pointer arrays. You were allocating for N 10x10 array of pointers.
What you intended was to allocate storage for N 10x10 info. To do so, you need to declare array as a pointer to array info [10][10]. Declared in this manner you are then free to allocate for N 10x10 array info in a single allocation (with the benefit of only requiring a single free (as opposed to allocating for info *** and requiring separate allocations for pointers, row-pointers, and finally elements-per-row). But to declare a pointer to array info [10][10], you must declare arrays as:
info (*array)[10][10];
(note: depending on how you use array throughout the code and whether initialization of all elements to some default value is beneficial, you can use calloc instead of malloc. calloc will allocate and zero all bytes (the additional time required to zero the new memory is generally negligible)).
And how can i do a realloc of array (in case i need more space)?
Since you have declared array as a pointer to array info[10][10] and have allocated storage in one shot, you simply need to realloc to create a larger block of memory for your storage. There are a number of allocation schemes to efficiently handle reallocation and you have the freedom to handle it however you want.
The rule-of-thumb is to generally declare storage for some reasonably anticipated number of pointers and 10x10 arrays of info. You keep a counter for the number of pointers and arrays currently allocated (say in nptrs). You keep a second counter of the number you have currently filled (say ndx -- short for index). When your index reaches the number of pointers and arrays allocated, you then realloc storage for somewhere between 1.5 - 2 times more storage, update your counter for nptrs and keep going until ndx == nptrs again, and repeat.
A short example may help. Since the members of info are undefined, lets just use a simple pointer to array int [10][10] for the example. The process would be the same for any collection, the only difference being sizeof *array would change the number of bytes allocated for each 10x10 array. (if you have additional members of info requiring dynamic allocation -- that would be an additional requirement)
When reallocating, always assign the return realloc to a temporary pointer. If realloc fails, it returns NULL and if you assign that to your original pointer -- you have just created a memory leak and lost the reference to your original block of memory. By using a temporary pointer, if realloc fails, your original data, and the pointer to it, remain valid.
A example that simply fills each 10x10 array with a constant number (e.g. 1, 2, 3, ...) and calls realloc twice to increase allocation for the 10x10 blocks from 8 to 16 and finally 32 would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NMTRX 8 /* if you need constants, then #define one (or more) */
#define MSIZE 10 /* don't use "magic numbers" in your code, unless */
#define NTEST 24 /* mandatory (like scanf field-width modifiers) */
/** set single MSIZExMSIZE array to n */
void set_m_to_n (int m[MSIZE][MSIZE], int n)
{
for (int i = 0; i < MSIZE; i++)
for (int j = 0; j < MSIZE; j++)
m[i][j] = n;
}
/** print single MSIZExMSIZE array */
void print_m (int m[MSIZE][MSIZE])
{
for (int i = 0; i < MSIZE; i++) {
for (int j = 0; j < MSIZE; j++)
printf (" %2d", m[i][j]);
putchar ('\n');
}
}
/** realloc to twice 'sz * *nelement' bytes returning
* pointer to reallocated block on success, NULL otherwise.
*/
void *realloc_2x (void *ptr, size_t sz, size_t *nelem)
{
char *memptr = realloc (ptr, 2 * *nelem * sz);
if (memptr == NULL) {
perror ("realloc-m");
return NULL;
} /* optionally zero all new memory */
memset (memptr + *nelem * sz, 0, *nelem * sz);
*nelem *= 2; /* update nelem (nptrs) to reflect new allocation */
return memptr; /* return pointer to new block for assignment */
}
int main (void) {
size_t ndx = 0, /* index */
nptrs = NMTRX; /* initial pointers to allocate */
int (*m)[MSIZE][MSIZE]; /* pointer to MSIZExMSIZE array */
m = calloc (nptrs, sizeof *m); /* allocate & initialize zero */
if (m == NULL) { /* validate allocation */
perror ("calloc-m");
exit (EXIT_FAILURE);
}
for (ndx = 0; ndx < NTEST; ndx++) { /* loop filling NTEST arrays */
if (ndx == nptrs) { /* check if index reached allocation */
void *tmp = realloc_2x (m, sizeof *m, &nptrs); /* realloc_2x */
if (tmp == NULL)/* validate reallocation */
break; /* don't exit on failure, original data good */
m = tmp; /* assign reallocated block to m */
}
set_m_to_n (m[ndx], ndx + 1); /* set array values to ndx+1 */
}
for (size_t i = 0; i < ndx; i++) { /* output all MSIZExMSIZE arrays */
printf ("\nm[%2zu]:\n", i);
print_m (m[i]);
}
free (m); /* free allocated memory */
return 0;
}
Example Use/Output
The output is simply the pointer and each 10x10 block of numbers:
$ ./bin/arr3d_dyn_ptr2d
m[ 0]:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
m[ 1]:
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
...
m[23]:
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
Memory Use/Error Check
$ valgrind ./bin/arr3d_dyn_ptr2d
==25240== Memcheck, a memory error detector
==25240== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25240== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25240== Command: ./bin/arr3d_dyn_ptr2d
==25240==
m[ 0]:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
m[ 1]:
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
...
m[23]:
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
==25240==
==25240== HEAP SUMMARY:
==25240== in use at exit: 0 bytes in 0 blocks
==25240== total heap usage: 3 allocs, 3 frees, 22,400 bytes allocated
==25240==
==25240== All heap blocks were freed -- no leaks are possible
==25240==
==25240== For counts of detected and suppressed errors, rerun with: -v
==25240== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.
You can use the following solution:
info (*array)[10][10]=malloc(N*sizeof(*array)); //declares pointer to 2d array

Looping through a Vector

I am using Rstudio and trying to create a function that will loop through a vector and perform a calculation with a while condition. The function should then return a data frame with the entered vector in one column and the number of iterations it took to satisfy the while condition in the another.
I have already created a function that preformed the calculation with the while condition which serves as the basic operation for the function I am having problems with. Here it is:
t5<-function(x){
z=x
while(x != 1){
if(x %% 2 == 0)
x= x/2
else x= (3 * x +1)
z=c(z, x)
}
return (z)
}
Here is what I have for the new function...my problem function (t7):
t7<-function(x){
y=0
i=0
for(i in 1:length(x)){
y[i]=length(t5(x[i]))-1
print(y[i])
}
#m<-data.frame(x, y[i])
}
I had it print y[i] because that is the only way the function does something. here is the output it shows (which is only half of what I need):
t7(2:10)
[1] 1
[1] 7
[1] 2
[1] 5
[1] 8
[1] 16
[1] 3
[1] 19
[1] 6
Can anybody help me understand how to make t7(2:10) run through this array and return a data frame listing the array and the number of iterations it took to reach the number 1 for each number in the array? Any help would be appreciated.
You can obtain the vector you need with the sapply function:
data.frame(x=2:10, iters=sapply(2:10, function(x) length(t5(x))-1))
# x iters
# 1 2 1
# 2 3 7
# 3 4 2
# 4 5 5
# 5 6 8
# 6 7 16
# 7 8 3
# 8 9 19
# 9 10 6

Resources