When you malloc, you encounter that you can substitute values for areas that you do not have, and you can also output them.What is the reason why we can do such a thing using an area that we don't have secured?
I think this behavior is unexpected and could cause bugs.
In the following case, I have secured 4 chars in malloc, so I understand that I can write from p[0] to p[3].
On the other hand, you can also write characters to p[4] and p[5] and see them in the subsequent output.
#include<iostream>
using namespace std;
int main() {
char*p;
p=(char*)malloc(sizeof(char)*4);
p[0] = 'a';
p[1] = 'b';
p[2] = 'c';
p[3] = 'd';
// You can also write p[4], p[5]!
p[4] = 'e';
p[5] = 'f';
cout<<p<<endl;//abcdef
free(p);
}
Managing memory in bytes is too expensive.Therefore, it is managed in units that are at least larger than sizeof(void*)
.
It is managed on a block-by-block basis and can be read and written beyond the range.
It may cause bugs
That's right, and to compensate for the weaknesses of C language, C++ language uses std::array
and , reff="nofor, Classes such as ">std::string
are available.None of these classes have C-language compatible operator[]
as well as at()
for range checking.The latter gets an std::out_of_range
exception when accessing out of range.
Metropolis gave me an example of gcc, so Microsoft Visual C++ too.
The Visual C++ Compiler incorporates the C/C++ Code Analysis feature.With this, the code in the questionnaire is
at compile time.source.cpp(14):warning C6200:Index '4' is out of valid index range '0' to '3' for non-stack buffer 'p'.
source.cpp(15): warning C6200: Index '5' is out of valid index range '0' to '3' for non-stack buffer 'p'.
source.cpp(9):warning C6011:Dereferencing NULL pointer 'p'.
source.cpp(14): warning C6386: Buffer overrun while writing to 'p': the writable size is '4' bytes, but '5' bytes right be written.
That's how C6200 warning and C6386 warning appear.In line 9, C6011 warning points to the possibility that malloc
will fail to secure memory and return NULL
.
In addition, in a debug build, malloc
switches to _malloc_dbg
from the initialized memory to
_malloc_dbg
Therefore,
cout<<p<endl;//abcdef
This line stops printing incorrectly (because \0
for string termination is not found).
Of course, there is also a function equivalent to _GLIBCXX_DEBUG
, which detects out-of-range access and reports errors when free
.
Incidentally, recent gcc adds code to perform a boudary check when compiling by specifying the -D_GLIBCXX_DEBUG
option.
====
x.cc
====
# include <iostream>
# include <iterator>
# include <array>
int main() {
std::array<int,4>p;
p[0]='a'; p[1]='b'; p[2]='c'; p[3]='d'; p[4]='e'; p[5]='f';
std::copy(p.begin(), p.begin()+6, std::ostream_iterator<char>(std::cout));
std::cout<<"\n";
}
$ g++ -- version
g++ (Ubuntu 7.3.0 - 16 ubuntu 3) 7.3.0
$ g++-ox x.cc &&./x
abcdef
## Define_GLIBCXX_DEBUG
$ g++-D_GLIBCXX_DEBUG-ox x.cc & ./x
/usr/include/c++/7/debug/array: 155:
Error: attempt to subscribe container with out-of-bound index 4, but
container only holds 4 elements.
Objects involved in the operation:
sequence "this" @0x0x7ffff151c6a10 {
type=std::__debug::array<int,4ul>;
}
Aborted (core dumped)
Other tools include cppcheck-tool for static C/C++ code analysis.
$cppcheck x.cc
Checking x.cc...
x.cc:10: (error) Array'p[4]'accessed at index4, which is out of bounds.
x.cc:10: (error) Array'p[4]'accessed at index 5, which is out of bounds.
Is it just that C/C++ doesn't check the array size?
It could be a cause of bugs
This has been said from the beginning in C language and is one of the factors that is considered dangerous for beginners.
In that sense, Java/C# is safe.
On the other hand, in the C source, there is only a declaration of chara[1];, and in the old source, it is widely seen that the substance is secured by a linker or the like. (Although not malloc()
© 2024 OneMinuteCode. All rights reserved.