Find the K-Beauty of a Number Unexpected Runtime Error - c++

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;
}
};

Related

LeetCode C++ Convert char[] to string, throws AddressSanitizer: stack-buffer-overflow error

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);

C++ memcpy not copying as expected

BYTE* uMemory;
std::string data = "00 00 00 2D 01 00 B0 F9 1E 00"
data.erase(remove_if(data.begin(), data.end(), isspace), data.end());
int address = 0;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
int num2 = std::stoi(data_1, 0, 16);
memcpy(&uMemory + address, &num2, 2);
address++;
}
I'm trying to copy this into memory (2E 01 00 00 00 2D 01 00 B0 F9 1E 00) for uMemory but I don't understand the logic of it.
No matter the amount of bytes I want it to copy it always ends up like this in memory:
00 00 00 00 00 00 00 00 00 01 00 00 2D 00 00 00 01 00 00 00 00 00 00 00 B0 00 00 00 F9 00 00 00 1E 00 00 00
Your immediate problem here is that uMemory is a pointer, and in the line
memcpy(&uMemory + address, &num2, 2);
you are forming a pointer to a pointer. &uMemory has type BYTE**, so when you do pointer arithmetic you're moving over one pointer-width each time, which is apparently 4 bytes on your platform judging by your output.
You're also clobbering a random section of memory of when you write here, likely the memory holding the data object itself (since that's what's declared immediately after the pointer.)
This was my solution. I would love some alternatives for better coding practices if possible.
std::atomic<BYTE> uMemory[256];
int address = 0;
std::vector<BYTE> array;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
DWORD num2 = std::stoi(data_1, 0, 16);
array.push_back(num2);
}
std::copy(std::begin(array), std::end(array), std::begin(uMemory));
The only thing I'm not understanding is that I have to have std::atomic in order for the memory to not become random. Is there a different way of doing this?

Getting e_lfanew from a dll, yielding E8 and not F8?

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.

Memory Leak with Openssl when allocating memory for X509_STORE

I am using openssl in my project. When I exit my application I get "Detected memory leaks!" in Visual Studio 2013.
Detected memory leaks!
Dumping objects ->
{70202} normal block at 0x056CB738, 12 bytes long.
Data: <8 j > 38 E8 6A 05 00 00 00 00 04 00 00 00
{70201} normal block at 0x056CB6E8, 16 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{70200} normal block at 0x056CB698, 20 bytes long.
Data: < l > 00 00 00 00 E8 B6 6C 05 00 00 00 00 04 00 00 00
{70199} normal block at 0x056AE838, 12 bytes long.
Data: < l > 04 00 00 00 98 B6 6C 05 00 00 00 00
{70198} normal block at 0x056CB618, 64 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{70197} normal block at 0x056CB578, 96 bytes long.
Data: < l 3 3 > 18 B6 6C 05 00 FE C0 33 C0 FD C0 33 08 00 00 00
Object dump complete.
When I add
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(70202);
to main main function I always get a breakpoint at the allocation of the x509 store, no matter for which of the 6 numbers (70202,...) I set the break point.
I initialize and uninitialize the x509 store in a class' constructor and destructor (see below).
Is there anything else I need to look out for when using the x509_STORE?
Foo::CSCACerts::CSCACerts(void)
{
m_store = X509_STORE_new();
}
Foo::CSCACerts::~CSCACerts(void)
{
X509_STORE_free( m_store );
}

(C++) Weird bitmap issue - Colors in grayscale

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.