Why you can write to areas that you don't have when you malloc

Asked 2 years ago, Updated 2 years ago, 34 views

Question

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.

example

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

c++

2022-09-30 17:48

3 Answers

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_dbgTherefore,

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.


2022-09-30 17:48

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.


2022-09-30 17:48

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


2022-09-30 17:48

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.