I'm asking myself, how you could improve code. If encountered following problem:
int i = 10;
int s = i * 12;
int main(){ }
When you look at the code in the PE-format, you notice, that neither i nor s is declared in the .data segment, despite the fact that their value could have been precalculated. They get initialized in runtime.
Here I have an example of another Code which has the same phenomenon. The Values were also declared like in the example above
View in Debugger before passing EntryPoint:
0133BF7C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0133BF8C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
After passing the EntryPoint:
0133BF7C E9 01 00 00 DF 02 00 00 64 00 00 00 00 00 00 00 é...ß...d.......
0133BF8C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
How can I declare a variable with an initial value in .data Section in C++ to save the precious computation time?
Or is the .data section never initialized with something before the execution starts?
If these are compile time constants, use constexpr.
constexpr int i = 10;
constexpr int s = i * 12;
Starting in C++17 these are also inline variables so you can declare them in a header file and not worry about having multiple definitions.
If these are not constants, but you want them to be constant initialized, then you can at least use static to make them have internal linkage which makes the optimization more likely to happen. Starting in C++20 you can use constinit to specify that the variable is to have static initialization, but can be changed later on in the program.
Related
I was recently doing the first question in the Leetcode Biweekly Competition 78, and I received an unexpected runtime error which I couldn't understand, especially since I had written similar code before which worked fine. I'm quite new to programming and these competitions, please tell me what this Runtime Error means and how I could change my code to fix it.
class Solution {
public:
int divisorSubstrings(int num, int k) {
string b=to_string(num);
string a="";
int x;
int ans=0;
for(int i=0;i<=b.size()-k;++i){
for(int j=i;i<i+k;++j){
a+=b[j];
}
x=stoi(a);
if(num%x==0){
++ans;
}
}
return ans;
}
};
And the error:
=================================================================
==33==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffca3ed0900 at pc 0x000000343d81 bp 0x7ffca3ed0890 sp 0x7ffca3ed0888
READ of size 1 at 0x7ffca3ed0900 thread T0
#2 0x7fe89b85d0b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Address 0x7ffca3ed0900 is located in stack of thread T0 at offset 96 in frame
This frame has 4 object(s):
[32, 40) '__endptr.i'
[64, 96) 'b' <== Memory access at offset 96 overflows this variable
[128, 160) 'a'
[192, 193) 'ref.tmp'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
0x1000147d20d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d20e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d20f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d2100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d2110: 00 00 00 00 f1 f1 f1 f1 f8 f2 f2 f2 00 00 00 00
=>0x1000147d2120:[f2]f2 f2 f2 00 00 00 00 f2 f2 f2 f2 f8 f3 f3 f3
0x1000147d2130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d2140: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x1000147d2150: 01 f2 04 f2 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d2160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000147d2170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==33==ABORTING
If you need the question, it is at https://leetcode.com/contest/biweekly-contest-78/problems/find-the-k-beauty-of-a-number/
Thanks
Your problem is this line of code:
for(int j=i;i<i+k;++j){
You have two habits you should break. First, you don't use white space. That makes the error in this line much harder to read. Second, you use very short variable names. That ALSO makes the error in this line harder to read.
That for-loop loops forever. The problem is the center clause:
i < i + k
Notice how obvious it is when I add spaces? This problem will get worse as you get older and your eyes get older. The code begins to resemble a wall of unreadable text. Old farts like me won't be able to read your code.
So please, add a little white space. I would have written that line like this:
for (int j = i; j < i + k; ++j) {
Yes, it takes more horizontal space. Space is cheap. Bugs are expensive.
Note that I still think this code is going to go out of range of b's size, so you might still have issues.
Here's the accepted solution modified from your snippet. Review the changes made.
class Solution {
public:
int divisorSubstrings(int num, int k) {
string b = to_string(num);
int ans = 0;
for(int i = 0; i <= b.size() - k; i++) { // the error causing crash
string a = ""; // keep declation close to it's usage, compiler will optimize declaration
for(int j = i; j < i + k; j++) a += b[j];
int x = stoi(a);
if (!x) continue; // you might not want to devide by 0
if( num % x == 0 ) ans++;
}
return ans;
}
};
I'm learning C++, and on LeetCode, converting a char[] to a string gives a AddressSanitizer: stack-buffer-overflow error.
string test1() /* Line 70 */
{
char test[] = "11";
return string(test);
}
string test2() /* Line 76 */
{
char test[] = {'1', '1'};
return string(test);
}
int main()
{
cout << test1() << endl;
cout << test2() << endl;
}
In this code above, test1 returns "11" and test2 gives the error below with ASAN on. Why does this happen? Aren't they just different ways to initialize a char array?
==87465==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffee2400c22 at pc 0x00010d837634 bp 0x7ffee2400ad0 sp 0x7ffee2400290
READ of size 3 at 0x7ffee2400c22 thread T0
pc_0x10d837633###func_wrap_strlen###file_<null>###line_3###obj_(libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1a633)
pc_0x10d803a14###func_std::__1::char_traits<char>::length(char const*)###file___string###line_253###obj_(CCC:x86_64+0x100005a14)
pc_0x10d803950###func_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*)###file_string###line_819###obj_(CCC:x86_64+0x100005950)
pc_0x10d80326c###func_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*)###file_string###line_817###obj_(CCC:x86_64+0x10000526c)
pc_0x10d80338f###func_test2()###file_p67-add-binary.cpp###line_79###obj_(CCC:x86_64+0x10000538f)
pc_0x10d803569###func_main###file_p67-add-binary.cpp###line_85###obj_(CCC:x86_64+0x100005569)
pc_0x7fff6cf80cc8###func_start###file_<null>###line_2###obj_(libdyld.dylib:x86_64+0x1acc8)
Address 0x7ffee2400c22 is located in stack of thread T0 at offset 34 in frame
pc_0x10d80328f###func_test2()###file_p67-add-binary.cpp###line_77###obj_(CCC:x86_64+0x10000528f)
This frame has 1 object(s):
[32, 34) 'test' (line 78) <== Memory access at offset 34 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1a633) in wrap_strlen+0x183
Shadow bytes around the buggy address:
0x1fffdc480130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdc480140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdc480150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdc480160: f1 f1 f1 f1 f8 f2 f8 f3 00 00 00 00 00 00 00 00
0x1fffdc480170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1fffdc480180: f1 f1 f1 f1[02]f3 f3 f3 00 00 00 00 00 00 00 00
0x1fffdc480190: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x1fffdc4801a0: f8 f8 f8 f2 f2 f2 f2 f2 00 00 00 f3 f3 f3 f3 f3
0x1fffdc4801b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdc4801c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdc4801d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
If you want your char * to be processed properly as a string, you must make sure it's null-terminated:
char test[] {'1', '1', '\0'};
String literals do that automatically. "11" is the same as {'1', '1', '\0'}.
Alternatively, you can pass the number of characters to read:
string str(test, sizeof test);
I'm reading a DLL file to a buffer (pSrcData), from here I wanted print the e_lfanew
bool readDll(const char* dllfile)
{
BYTE* pSrcData;
std::ifstream File(dllfile, std::ios::binary | std::ios::ate);
auto FileSize = File.tellg();
pSrcData = new BYTE[static_cast<UINT_PTR>(FileSize)];
File.seekg(0, std::ios::beg);
File.read(reinterpret_cast<char*>(pSrcData), FileSize);
File.close();
std::cout << std::hex << reinterpret_cast<IMAGE_DOS_HEADER*>(pSrcData)->e_lfanew;
pOldNtHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(pSrcData + reinterpret_cast<IMAGE_DOS_HEADER*>(pSrcData)->e_lfanew);
return true;
}
Output: E8
Opening the dll in HxD i get this (address 0000000 - 00000030):
4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 F8 00 00 00
Meaning e_lfanew should be F8. However, I get E8 when running the code above. Can anyone see what I'm doing wrong?
Addition:
Getting e_magic works as std::cout << std::hex << reinterpret_cast<IMAGE_DOS_HEADER*>(pSrcData)->e_magic yields 5a4d, using little endian translated to 4D 5A
Sorry, I found setting the configuration in Visual Studio 2019 to x86 Release sets e_lfanew to F9 and x86 Debug sets e_lfanew to E8. I was comparing different debug/release versions.
Previously everything was ok. But after the recent CRAN checks, many warnings are encountered. Here it is
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:721:30:
runtime error: member call on address 0x7fd0281f3d00 which does not
point to an object of type 'tbb::internal::scheduler' 0x7fd0281f3d00:
note: object is of type
'tbb::internal::custom_schedulertbb::internal::IntelSchedulerTraits'
00 00 00 00 b8 db 86 28 d0 7f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 80 ef ff 27 ^~ vptr for
'tbb::internal::custom_schedulertbb::internal::IntelSchedulerTraits'
SUMMARY: AddressSanitizer: undefined-behavior
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:721:30
in
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/parallel_reduce.h:177:19:
runtime error: member call on address 0x7fd0281d3b40 which does not
point to an object of type 'tbb::task' 0x7fd0281d3b40: note: object
has invalid vptr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~ invalid vptr SUMMARY:
AddressSanitizer: undefined-behavior
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/parallel_reduce.h:177:19
in
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:688:9:
runtime error: member call on address 0x7fd0281d3b40 which does not
point to an object of type 'tbb::task' 0x7fd0281d3b40: note: object
has invalid vptr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~ invalid vptr SUMMARY:
AddressSanitizer: undefined-behavior
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:688:9
in
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/parallel_reduce.h:178:31:
runtime error: member call on address 0x7fd0281d3b40 which does not
point to an object of type 'tbb::task' 0x7fd0281d3b40: note: object
has invalid vptr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~ invalid vptr SUMMARY:
AddressSanitizer: undefined-behavior
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/parallel_reduce.h:178:31
in
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:946:23:
runtime error: member call on address 0x7fd0281f3d00 which does not
point to an object of type 'tbb::internal::scheduler' 0x7fd0281f3d00:
note: object is of type
'tbb::internal::custom_schedulertbb::internal::IntelSchedulerTraits'
00 00 00 00 b8 db 86 28 d0 7f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 80 ef ff 27 ^~ vptr for
'tbb::internal::custom_schedulertbb::internal::IntelSchedulerTraits'
SUMMARY: AddressSanitizer: undefined-behavior
/data/gannet/ripley/R/test-clang/RcppParallel/include/tbb/task.h:946:23
in Loading required package: diagram Loading required package: shape
Loading required package: DiagrammeR Loading required package:
survival testthat results
================================================================ OK: 87 SKIPPED: 0 FAILED: 0 There were 11 warnings (use warnings() to see
them)
I am not a C++ expert. How one can fix these issues?
Please help so that a new version of the package can be submitted to CRAN.
I have a weird issue with creating an Bitmap in C++. I'm using the BITMAPFILEHEADER and BITMAPINFOHEADER Structure for creating an 8bit grayscale image. Bitmap data is coming from a camera over DMA as unsigned char an has exactly the same lenghts as expected. Saving the image an opening it, it contains colors?!
The way it should be: http://www.freeimagehosting.net/qd1ku
The way it is: http://www.freeimagehosting.net/83r1s
Do you have any Idea where this is comping from?
The Header of the bitmap is:
42 4D 36 00 04 00 00 00 00 00 36 00 00 00 28 00
00 00 00 02 00 00 00 02 00 00 01 00 08 00 00 00
00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00
Info-Header:
42 4D Its a Bitmap
36 00 04 00 Size of Bitmap = 0x04 00 36 - Header-Size = 512x512
00 00 00 00 Reserved
36 00 00 00 Offset = Sizeof(Bitmapinfoheader);
28 00 00 00 Sizeof(Bitmapinfoheader);
00 02 00 00 =0x200 = 512 px.
00 02 00 00 same
01 00 = 1 - Standard. Not used anymore.
08 00 Color dept = 8 bit.
00 00 00 00 Compression: 0 = none.
00 00 00 00 Filesize or zero
00 00 00 00 X-Dot-Per-Meter, may be left 0
00 00 00 00 y-Dot-Per-Meter, may be left 0
00 00 00 00 If zero, all 255 colors are used
00 00 00 00 If zero, no color table values are used
Do you have any Idea where this comes from?
Under windows, if you do not supply a palette for your 8 bit image a system default one is provided for you. I do not recall offhand the win32 way to add a palette, but it should be as simple as creating a 256 element char array where the value of each entry is the same as its index, and writing it out to your file at the appropriate point and updating the offset parameter, etc.